monadic 0.1.14

macro to define Haskell style monadic action blocks
Documentation

rust-monadic

A macro to write Haskell style monadic code

for IntoIterator (iterables) as monads

Each step monad expression is flat_mapped with the rest into a lazy FlatMap expression which implements IntoIterator with lambdas as move closures capturing the environment and argument. The lambda body type should also be an instance of IntoIterator and it will be recursively parsed as monadic.

The trait Monad is defined in module monad as supertrait of IntoIterator.

You can use:

  • Option::pure( return_expresion) to return an expression value
  • v <- monadic_expression to use the monad result
  • _ <- monadic_expression to ignore the monad result
  • let z = expression to combine monad results
  • guard boolean_expression to filter results

Note: let, within the macro, introduces an expression, not a block.

Example: monadic comprehensions à la Haskell

// examples/comprehension.rs

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

fn main() {
    let xs = monadic!{ 
    
        x <- 1..7;
        y <- 1..x;
        guard (&y).is_odd() ;
        let z = &y + 1 ;
        Option::pure((x, z)) 
        
    }.collect::<Vec<(i32,i32)>>();
    
    println!("result: {:?}", xs); 
}

$ cargo run --example comprehension

result: [(2, 2), (3, 2), (4, 2), (4, 4), (5, 2), (5, 4), (6, 2), (6, 4), (6, 6)]