about summary refs log tree commit diff
path: root/src/lib/list.rs
blob: 342b50ff9a348c022e82e394202536a865e4ddd4 (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
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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
import option::some;
import option::none;

// FIXME: It would probably be more appealing to define this as
// type list[T] = rec(T hd, option[@list[T]] tl), but at the moment
// our recursion rules do not permit that.

tag list[T] {
    cons(T, @list[T]);
    nil;
}

fn from_vec[T](vec[T] v) -> list[T] {
    auto l = nil[T];
    // FIXME: This would be faster and more space efficient if it looped over
    // a reverse vector iterator. Unfortunately generic iterators seem not to
    // work yet.
    for (T item in vec::reversed(v)) {
        l = cons[T](item, @l);
    }
    ret l;
}

fn foldl[T,U](&list[T] ls, &U u, fn(&T t, &U u) -> U f) -> U {
    alt(ls) {
        case (cons(?hd, ?tl)) {
            auto u_ = f(hd, u);
            be foldl[T,U](*tl, u_, f);
        }
        case (nil) {
            ret u;
        }
    }
}

fn find[T,U](&list[T] ls,
             (fn(&T) -> option::t[U]) f) -> option::t[U] {
    alt(ls) {
        case (cons(?hd, ?tl)) {
            alt (f(hd)) {
                case (none) {
                    be find[T,U](*tl, f);
                }
                case (some(?res)) {
                    ret some[U](res);
                }
            }
        }
        case (nil) {
            ret none[U];
        }
    }
}

fn has[T](&list[T] ls, &T elt) -> bool {
    alt(ls) {
        case (cons(?hd, ?tl)) {
            if (elt == hd) {
                ret true;
            } else {
                be has(*tl, elt);
            }
        }
        case (nil) { ret false; }
    }
}

fn length[T](&list[T] ls) -> uint {
    fn count[T](&T t, &uint u) -> uint {
        ret u + 1u;
    }
    ret foldl[T,uint](ls, 0u, bind count[T](_, _));
}

fn cdr[T](&list[T] ls) -> list[T] {
    alt (ls) {
        case (cons(_, ?tl)) {ret *tl;}
    }
}
fn car[T](&list[T] ls) -> T {
    alt (ls) {
        case (cons(?hd, _)) {ret hd;}
    }
}


fn append[T](&list[T] l, &list[T] m) -> list[T] {
    alt (l) {
        case (nil) {
            ret m;
        }
        case (cons(?x, ?xs)) {
            let list[T] rest = append[T](*xs, m);
            ret cons[T](x, @rest);
        }
    }
}


// Local Variables:
// mode: rust;
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// compile-command: "make -k -C .. 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
// End: