Yet another Rust algebraic effects library
#![ feature( coroutines, coroutine_trait) ]
use reffect:: * ;
struct Log ( String ) ;
impl Effect for Log {
type Resume = ( ) ;
}
struct Increment ( u32 ) ;
impl Effect for Increment {
type Resume = u32 ;
}
#[ effectful( Log ) ]
fn log_value < T : std:: fmt:: Debug > ( value : T ) -> T {
yield Log ( format ! ( "{:?}" , value) ) ;
value
}
#[ effectful( Increment ) ]
fn increment ( value : u32 ) -> u32 {
yield Increment ( value)
}
#[ effectful( Log , Increment ) ]
fn test_func ( ) -> u32 {
let value = log_value ( 1 ) . await ;
let value = increment ( value) . await ;
log_value ( value) . await ;
value
}
// Catch within effectful coroutines.
let ret = test_func ( ) . handle ( handler ! {
Log ( s) => println!( "{s}" ) ,
Increment ( i) if i < 10 => i + 1 ,
Increment ( i) => break i,
} ) ;
assert_eq ! ( ret. run( ) , 2 ) ;
// Catch in place.
let ret = catch ! ( test_func( ) . await {
Log ( s) => println!( "{s}" ) ,
Increment ( i) if i < 10 => i + 1 ,
Increment ( i) => break i,
} ) ;
assert_eq ! ( ret, 2 ) ;
#![ feature( coroutines, coroutine_trait) ]
#![ feature( impl_trait_in_assoc_type) ]
#![ feature( lifetime_capture_rules_2024) ]
use reffect:: * ;
#[ group]
trait Counter {
fn inc ( delta : u32 ) ;
fn get ( ) -> u32 ;
}
struct CounterImpl ( u32 ) ;
#[ group_handler]
impl Counter for CounterImpl {
fn inc ( & mut self , delta : u32 ) {
self . 0 += delta;
}
fn get ( & self ) -> u32 {
self . 0
}
}
struct CounterAmplifier ( u32 ) ;
#[ group_handler]
#[ effectful( Counter ) ]
impl Counter for CounterAmplifier {
fn inc ( & self , delta : u32 ) {
Counter :: inc ( delta * self . 0 ) . await
}
fn get ( & self ) -> u32 {
Counter :: get ( ) . await / self . 0
}
}
let coro = effectful_block ! {
#![ effectful( Counter ) ]
let counter = Counter :: get( ) . await ;
if counter < 10 {
Counter :: inc( 10 - counter) . await ;
}
Counter :: get( ) . await
} ;
let coro = coro. catch0 ( CounterAmplifier ( 10 ) ) ;
let mut counter = CounterImpl ( 0 ) ;
let coro = coro. handle ( & mut counter) ;
assert_eq ! ( coro. run( ) , 10 ) ;
assert_eq ! ( counter. 0 , 100 ) ;