1
+ // xfail-stage0
2
+ // Uses foldl to exhibit the unchecked block syntax.
3
+ use std;
4
+
5
+ import std:: list:: * ;
6
+
7
+ // Can't easily be written as a "pure fn" because there's
8
+ // no syntax for specifying that f is pure.
9
+ fn pure_foldl < @T , @U > ( ls : & list < T > , u : & U , f : & block ( & T , & U ) -> U ) -> U {
10
+ alt ls {
11
+ nil. { u }
12
+ cons( hd, tl) { f ( hd, pure_foldl ( * tl, f ( hd, u) , f) ) }
13
+ }
14
+ }
15
+
16
+ // Shows how to use an "unchecked" block to call a general
17
+ // fn from a pure fn
18
+ pure fn pure_length < @T > ( ls : & list < T > ) -> uint {
19
+ fn count < T > ( _t : & T , u : & uint ) -> uint { u + 1 u }
20
+ unchecked {
21
+ pure_foldl( ls, 0 u, count)
22
+ }
23
+ }
24
+
25
+ pure fn nonempty_list<@T >( ls: & list<T >) -> bool {
26
+ pure_length ( ls) > 0 u
27
+ }
28
+
29
+ // Of course, the compiler can't take advantage of the
30
+ // knowledge that ls is a cons node. Future work.
31
+ // Also, this is pretty contrived since nonempty_list
32
+ // could be a "tag refinement", if we implement those.
33
+ fn safe_head<@T >( ls: & list<T >) : nonempty_list ( ls) -> T { car( ls) }
34
+
35
+ fn main ( ) {
36
+ let mylist = cons ( @1 u, @nil) ;
37
+ // Again, a way to eliminate such "obvious" checks seems
38
+ // desirable. (Tags could have postconditions.)
39
+ check ( nonempty_list ( mylist) ) ;
40
+ assert ( * ( safe_head ( mylist) ) == 1 u) ;
41
+ }
0 commit comments