I'm tinkering around with developing an algebraic effect system in Rust.
Heavy inspiration is taken from the old eff project. The basic idea is that each effectful function is a Generator that yields Coprod!(Each, Different, Effect, Raised):
struct A;
struct B;
struct C;
impl Effect for A {
type Output = ();
}
impl Effect for B {
type Output = i32;
}
impl Effect for C {
type Output = ();
}
fn make_effectful_function() -> impl Effectful<Output = String, Effect = Coprod!(A, B, C)> {
|| {
let a: () = raise!(A);
let b: i32 = raise!(B);
let c: () = raise!(C);
b.to_string()
}
}
With each of those raise! macros expanding to something like:
{
type Effect = Coprod!(A, B, C);
type Output = Coprod!((), i32, ());
let (send, recv): (Sender<Effect>, Receiver<Output>) = channel();
yield (Effect::inject(B), send);
let output = recv.recv();
let output = output.uninject::<i32, _>(output); // in reality this remembers the Index used to inject B
output
}
Coproduct::map() for handling effects
Whoever drives these effectful computations needs to handle the raised effects, mapping each possible effect to its proper output type. Here's how that could work if Coproduct had a map() like HList does:
let mut effectful = make_effectful_function();
let result = loop {
match effectful.poll() {
Poll::Complete(result) => break result,
Poll::Effect(effect, resume) => {
let output = effect.map(poly![
|A| (),
|B| 100,
|C| (),
]);
resume.send(output);
},
}
}
Way forward?
I'd be willing to take a stab at adding these bits of functionality, but don't know how I'd best go about that. Like, should I repurpose HMappable to also work with Coproduct? Or should I create a brand new CMappable?
I'm tinkering around with developing an algebraic effect system in Rust.
Heavy inspiration is taken from the old
eff
project. The basic idea is that each effectful function is aGenerator
that yieldsCoprod!(Each, Different, Effect, Raised)
:With each of those
raise!
macros expanding to something like:Coproduct::map()
for handling effectsWhoever drives these effectful computations needs to handle the raised effects, mapping each possible effect to its proper output type. Here's how that could work if
Coproduct
had amap()
likeHList
does:Way forward?
I'd be willing to take a stab at adding these bits of functionality, but don't know how I'd best go about that. Like, should I repurpose
HMappable
to also work withCoproduct
? Or should I create a brand newCMappable
?