summary refs log tree commit diff
path: root/src/test/run-pass/monad.rs
blob: d5a05d47cf066188f1e4525530414da221b59928 (plain)
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
iface monad<A> {
    fn bind<B>(fn(A) -> self<B>) -> self<B>;
}

impl <A> of monad<A> for [A] {
    fn bind<B>(f: fn(A) -> [B]) -> [B] {
        let mut r = [];
        for elt in self { r += f(elt); }
        r
    }
}

impl <A> of monad<A> for option<A> {
    fn bind<B>(f: fn(A) -> option<B>) -> option<B> {
        alt self {
          some(a) { f(a) }
          none { none }
        }
    }
}

fn transform(x: option<int>) -> option<str> {
    x.bind {|n| some(n + 1)}.bind {|n| some(int::str(n))}
}

fn main() {
    assert transform(some(10)) == some("11");
    assert transform(none) == none;
    assert ["hi"].bind {|x| [x, x + "!"]}.bind {|x| [x, x + "?"]} ==
        ["hi", "hi?", "hi!", "hi!?"];
}