#![deny(unsafe_code, nonstandard_style)]
#![forbid(rust_2018_idioms)]
#![warn(unreachable_pub, missing_debug_implementations)]
#![allow(rustdoc::bare_urls)]
#![doc = include_str!("../README.md")]
#![cfg_attr(not(feature = "std"), no_std)]
pub use higher_derive::{Bifunctor, Functor};
pub mod semigroup;
#[doc(inline)]
pub use crate::semigroup::Semigroup;
pub mod monoid;
#[doc(inline)]
pub use crate::monoid::Monoid;
pub mod functor;
#[doc(inline)]
pub use crate::functor::Functor;
pub mod contra;
#[doc(inline)]
pub use crate::contra::Contravariant;
pub mod bifunctor;
#[doc(inline)]
pub use crate::bifunctor::Bifunctor;
pub mod profunctor;
#[doc(inline)]
pub use crate::profunctor::Profunctor;
pub mod pure;
#[doc(inline)]
pub use crate::pure::Pure;
pub mod apply;
#[doc(inline)]
pub use crate::apply::Apply;
pub mod bind;
#[doc(inline)]
pub use crate::bind::Bind;
pub mod applicative;
#[doc(inline)]
pub use crate::applicative::Applicative;
pub mod monad;
#[doc(inline)]
pub use crate::monad::Monad;
pub mod foldable;
#[doc(inline)]
pub use crate::foldable::Foldable;
pub mod algebras;
pub mod effect;
pub mod rings;
#[cfg(feature = "io")]
pub mod io;
#[macro_export]
macro_rules! run {
(yield $result:expr) => {
$crate::Pure::pure($result)
};
($result:expr) => {
$result
};
($binding:ident <= $comp:expr; $($tail:tt)*) => {
$crate::Bind::bind($comp, move |$binding| run!($($tail)*))
};
($comp:expr; $($tail:tt)*) => {
$crate::Bind::bind($comp, move |_| run!($($tail)*))
}
}
#[cfg(test)]
mod test {
#[test]
fn do_notation() {
assert_eq!(
run! {
x <= vec![1, 2];
y <= vec![x, x + 1];
yield (x, y)
},
vec![(1, 1), (1, 2), (2, 2), (2, 3)]
);
assert_eq!(
run! {
x <= 25u32.checked_div(2);
y <= x.checked_div(3);
z <= 9u32.checked_div(y);
yield x + y + z
},
Some(18)
);
assert_eq!(
run! {
x <= 5u32.checked_div(2);
y <= x.checked_div(8);
z <= 9u32.checked_div(y);
yield x + y + z
},
None
);
assert_eq!(
run! {
x <= 25u32.checked_div(2);
y <= x.checked_div(3);
z <= 9u32.checked_div(y);
Some(x + y + z)
},
Some(18)
);
assert_eq!(
run! {
2u32.checked_div(2);
2u32.checked_div(1)
},
Some(2)
);
assert_eq!(
run! {
2u32.checked_div(0);
2u32.checked_div(1)
},
None
);
assert_eq!(
run! {
s <= Some("64");
x <= s.parse::<u32>().ok();
y <= x.checked_div(2);
yield y
},
Some(32)
);
}
}