[][src]Crate monadic

Haskell style "monadic" macro 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.

To use pure to lift a value, a monad implementation must be used, 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

Some structures e.g. Range implement a supertrait of Iterator, so they are IntoIterator instances, but they are not recognized as instances of the defined Bind as supertrait of IntoIterator and its implementation for all IntoIterators, so the macro doesn't use the defined bind() but into_iter().flatmap()

Iterator and IntoIterator trait imports are predefined

use monadic::{monadic, Monad};
use num::Integer;

   // available in examples/comprehension.rs

   let xs = monadic!{ 

           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)) 
            
   }.collect::<Vec<(i32,i32)>>();
    
   println!("result: {:?}", xs); 

   // now with container and item references, available in examples/comprehension2.rs

   let ys = monadic!{ 
    
       &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)) 
        
   }.collect::<Vec<(i32,i32)>>();
    
   println!("result: {:?}", ys); 

Re-exports

pub use monad::Monad;

Modules

monad

Macros

monadic

converting monadic blocs of IntoIterator's as monads à la Haskell