diff options
| author | Graydon Hoare <[email protected]> | 2010-10-18 14:35:44 -0700 |
|---|---|---|
| committer | Graydon Hoare <[email protected]> | 2010-10-18 14:35:44 -0700 |
| commit | 783be711f51e4334693caba8b526335bdee95dd4 (patch) | |
| tree | 23865d9d8d8b03571ee61e239d9ea30384141a62 /src/lib | |
| parent | Roll back the expr->lval change. We're now LL(1) again. (diff) | |
| download | rust-783be711f51e4334693caba8b526335bdee95dd4.tar.xz rust-783be711f51e4334693caba8b526335bdee95dd4.zip | |
Flesh out the std.list module a touch.
Diffstat (limited to 'src/lib')
| -rw-r--r-- | src/lib/list.rs | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/src/lib/list.rs b/src/lib/list.rs index e73d2625..60c23a9e 100644 --- a/src/lib/list.rs +++ b/src/lib/list.rs @@ -1,9 +1,58 @@ +import util.option; +import util.some; +import util.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 foldl[T,U](&list[T] ls, U u, fn(&T t, U u) -> U f) -> U { + alt(ls) { + case (cons[T](?hd, ?tl)) { + auto u_ = f(hd, u); + // FIXME: should use 'be' here, not 'ret'. But parametric + // tail calls currently don't work. + ret foldl[T,U](*tl, u_, f); + } + case (nil[T]) { + ret u; + } + } +} + +fn find[T](&list[T] ls, + (fn(&T) -> option[T]) f) -> option[T] { + alt(ls) { + case (cons[T](?hd, ?tl)) { + alt (f(hd)) { + case (none[T]) { + // FIXME: should use 'be' here, not 'ret'. But parametric tail + // calls currently don't work. + ret find[T](*tl, f); + } + case (some[T](?res)) { + ret some[T](res); + } + } + } + case (nil[T]) { + ret none[T]; + } + } +} + +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](_, _)); +} // Local Variables: // mode: rust; |