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
//! //! 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](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, //! }; //! 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); //! # } //! ``` pub mod monad; pub mod intoiter;