macro_rules! mdo {
(
let $p: pat = $e: expr ; $( $t: tt )*
) => { ... };
(
let $p: ident : $ty: ty = $e: expr ; $( $t: tt )*
) => { ... };
(
$p: pat =<< $e: expr ; $( $t: tt )*
) => { ... };
(
$p: ident : $ty: ty =<< $e: expr ; $( $t: tt )*
) => { ... };
(
ign $e: expr ; $( $t: tt )*
) => { ... };
(
when $e: expr ; $( $t: tt )*
) => { ... };
(
ret $f: expr
) => { ... };
}
Expand description
Monadic do notation using duck typing
Syntax:
(instr)* ; ret expr
instr can be:
-
pattern =<< expression
: bind expression to pattern. abind
function must be in scope. -
let pattern = expression
: assign expression to pattern, as normal rust let. -
ign expression
: equivalent to_ =<< expression
-
when expression
: filter on the monad.ret
andmzero
functions must be in scope.
ยงExample
#[macro_use] extern crate mdo;
fn main() {
use mdo::iter::{bind, ret, mzero};
let l = mdo! {
x =<< 0i32..5; // assign x to [0, 5[
ign 0..2; // duplicate each value
when x % 2 == 0; // filter on even values
let y = x + 5; // create y
ret ret(y + 5) // return y + 5
}.collect::<Vec<_>>();
assert_eq!(l, vec![10, 10, 12, 12, 14, 14]);
}