-
Notifications
You must be signed in to change notification settings - Fork 21
/
Copy pathtransform.rs
61 lines (51 loc) · 1.83 KB
/
transform.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
//! Here, the Lunchtime and Log effects are both handled by invoking a third effect, Print. This is
//! known in effing_mad as "transforming" the effects. Print is then handled on its own and since it
//! is the only remaining effect the computation can then be run.
#![feature(coroutines)]
#![feature(coroutine_trait)]
use core::ops::ControlFlow;
use effing_mad::{effectful, handle, run, transform0, transform1, Effect};
fn main() {
let work = take_over_the_world();
// Log, Lunchtime -> Print, Lunchtime
// Introducing 1 new effect (Print) so must use transform1
let transformed = transform1(work, print_log);
// Print, Lunchtime -> Print
// Not introducing new effects so must use transform0
let transformed = transform0(transformed, print_lunchtime);
let handled = handle(transformed, |Print(message)| {
println!("{message}");
ControlFlow::Continue(())
});
run(handled);
}
struct Print(String);
impl Effect for Print {
type Injection = ();
}
struct Log(String, i32);
impl Effect for Log {
type Injection = ();
}
struct Lunchtime;
impl Effect for Lunchtime {
type Injection = ();
}
// I am running out of inspiration for the functions in these examples
#[effectful(Log, Lunchtime)]
fn take_over_the_world() {
yield Log("I intend to take over the world!".into(), 5);
yield Log("I'm off to get lunch first though".into(), 0);
yield Lunchtime;
yield Log("They're out of sausage rolls at the bakery!".into(), 100);
}
#[effectful(Print)]
fn print_log(Log(message, importance): Log) {
yield Print(format!("log (importance {importance}): {message}"));
}
#[effectful(Print)]
fn print_lunchtime(Lunchtime: Lunchtime) {
yield Print("lunchtime: in progress...".into());
std::thread::sleep(std::time::Duration::from_secs(3));
yield Print("lunchtime: failed!".into());
}