Skip to content

Instantly share code, notes, and snippets.

@shinkwhek
Last active July 11, 2018 12:04
Show Gist options
  • Save shinkwhek/42df259bd08a3efa18f1ee6e33418a25 to your computer and use it in GitHub Desktop.
Save shinkwhek/42df259bd08a3efa18f1ee6e33418a25 to your computer and use it in GitHub Desktop.
trait Monad<A, MA> {
fn _return(a: A) -> MA;
fn _bind<F>(self, f: F) -> MA
where
F: Fn(A) -> MA;
}
#[derive(Debug, PartialEq)]
enum Maybe<T> {
Just(T),
Nothing,
}
impl<A> Monad<A, Maybe<A>> for Maybe<A> {
fn _return(a: A) -> Maybe<A> {
Maybe::Just(a)
}
fn _bind<F>(self, f: F) -> Maybe<A>
where
F: Fn(A) -> Maybe<A>,
{
match self {
Maybe::Nothing => Maybe::Nothing,
Maybe::Just(a) => f(a),
}
}
}
fn add1(a: i64) -> Maybe<i64> {
Maybe::_return(a + 1)
}
fn main() {
println!("{:?}, {:?}", Maybe::_return(1), Maybe::Nothing::<i64>);
}
#[test]
fn id1() {
assert_eq!(Maybe::_return(1)._bind(add1), add1(1));
}
#[test]
fn id2() {
assert_eq!(Maybe::_return(1), Maybe::_return(1)._bind(Maybe::_return));
}
#[test]
fn associativity() {
let ma1 = Maybe::_return(1)._bind(add1);
let ma2 = ma1._bind(add1);
let ma3 = Maybe::_return(1)._bind(|a| add1(a)._bind(add1));
assert_eq!(ma2, ma3);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment