1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
//!
//! 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, 
//! being 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](https://doc.rust-lang.org/stable/core/iter/#for-loops-and-intoiterator) 
//!
//! Iterator and IntoIterator trait imports are [predefined](https://doc.rust-lang.org/std/prelude/index.html#prelude-contents)
//!
//! ```
//! # #[macro_use] extern crate monadic;
//! use num::Integer;
//! use monadic::{mdo, monad::{Bind, Monad}};
//!
//! // alternatively you may use monadic::monadic; the macro without interpositions.
//!
//! # fn main() {
//!    // 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,
//!                    };
//!            pure (x, z)
//!            
//!    }.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 ;
//!        pure (x, z)
//!        
//!    }.collect::<Vec<(i32,i32)>>();
//!    
//!    println!("result: {:?}", ys); 
//! # }
//! ```

pub mod monad;
pub mod intoiter;
pub mod monoid;
pub mod reader;
pub mod writer;
pub mod util;
pub mod state;
pub mod mio;