[−][src]Crate monadic
Haskell style block macros "mdo" and "monadic" where monad sources should be expressions of type instances of IntoIterator.
Each monad expression is flat_mapped with the lambda expression having the monad result variable as argument and the rest as its body, into a lazy FlatMap expression that is also an instance of IntoIterator, and can be collected into any instance of FromIterator.
The macro "mdo" (module monad
) uses the traits Bind (IntoIterator supertrait) and Monad (Bind supertrait) defined there.
The macro "monadic" (module intoiter
) uses IntoIterator into_iter() without interpositions.
To use pure
to lift a value, it has to be typed by a monad implementation,
beeing Option::pure(x) the least costly option, or just Some(x).
There are transitive implementation relations for some structures to be instances of IntoIterator:
All iterators implement IntoIterator where into_iter() returns the self iterator structure as documented
Iterator and IntoIterator trait imports are predefined
use num::Integer; use monadic::{mdo, monad::{Bind, Monad}}; // alternatively you may use monadic::monadic; the macro without interpositions. // available in examples/comprehension.rs let xs = mdo!{ x <- 1..7; y <- 1..x; guard (&y).is_odd() ; let z = match x.is_even() { true => &y + 1, _ => &y - 1, }; Option::pure((x, z)) // if Monad is in scope, anyway Some((x, z)) will do }.collect::<Vec<(i32,i32)>>(); println!("result: {:?}", xs); // now with container and item references, available in examples/comprehension2.rs let ys = mdo!{ &x <- &vec![1,2,3,4]; // with item refs (&x) in the lambda argument position guard x.is_odd() ; let z = x + 1 ; Option::pure((*x, z)) // if Monad is in scope, anyway Some((*x, z)) will do }.collect::<Vec<(i32,i32)>>(); println!("result: {:?}", ys);
Modules
intoiter | definition of IntoIterator based monadic macro of Haskell style monadic action blocks |
monad |
Macros
mdo | |
monadic | macro which uses IntoIterator as monad |