1implement Lists; 2 3include "lists.m"; 4 5# these will be more useful when p is a closure 6allsat[T](p: ref fn(x: T): int, l: list of T): int 7{ 8 for(; l != nil; l = tl l) 9 if(!p(hd l)) 10 return 0; 11 return 1; 12} 13 14anysat[T](p: ref fn(x: T): int, l: list of T): int 15{ 16 for(; l != nil; l = tl l) 17 if(p(hd l)) 18 return 1; 19 return 0; 20} 21 22map[T](f: ref fn(x: T): T, l: list of T): list of T 23{ 24 if(l == nil) 25 return nil; 26 return f(hd l) :: map(f, tl l); 27} 28 29filter[T](p: ref fn(x: T): int, l: list of T): list of T 30{ 31 if(l == nil) 32 return nil; 33 if(p(hd l)) 34 return hd l :: filter(p, tl l); 35 return filter(p, tl l); 36} 37 38partition[T](p: ref fn(x: T): int, l: list of T): (list of T, list of T) 39{ 40 l1: list of T; 41 l2: list of T; 42 for(; l != nil; l = tl l) 43 if(p(hd l)) 44 l1 = hd l :: l1; 45 else 46 l2 = hd l :: l2; 47 return (reverse(l1), reverse(l2)); 48} 49 50append[T](l: list of T, x: T): list of T 51{ 52 # could use the reversing loops instead if this is ever a bottleneck 53 if(l == nil) 54 return x :: nil; 55 return hd l :: append(tl l, x); 56} 57 58concat[T](l: list of T, l2: list of T): list of T 59{ 60 if(l2 == nil) 61 return l; 62 for(rl1 := reverse(l); rl1 != nil; rl1 = tl rl1) 63 l2 = hd rl1 :: l2; 64 return l2; 65} 66 67combine[T](l: list of T, l2: list of T): list of T 68{ 69 for(; l != nil; l = tl l) 70 l2 = hd l :: l2; 71 return l2; 72} 73 74reverse[T](l: list of T): list of T 75{ 76 rl: list of T; 77 for(; l != nil; l = tl l) 78 rl = hd l :: rl; 79 return rl; 80} 81 82last[T](l: list of T): T 83{ 84 # l must not be nil 85 while(tl l != nil) 86 l = tl l; 87 return hd l; 88} 89 90# find instance of x in l, return tail of l from x 91find[T](x: T, l: list of T): list of T 92 for { T => eq: fn(a, b: T): int; } 93{ 94 for(; l != nil; l = tl l) 95 if(T.eq(x, hd l)) 96 return l; 97 return nil; 98} 99 100# delete the first instance of x in l 101delete[T](x: T, l: list of T): list of T 102 for { T => eq: fn(a, b: T): int; } 103{ 104 loc := find(x, l); 105 if(loc == nil) 106 return l; 107 o: list of T; 108 for(; l != loc; l = tl l) 109 o = hd l :: o; 110 l = tl loc; 111 for(; o != nil; o = tl o) 112 l = hd o :: l; 113 return l; 114} 115 116pair[T1, T2](l1: list of T1, l2: list of T2): list of (T1, T2) 117{ 118 if(l1 == nil && l2 == nil) 119 return nil; 120 return (hd l1, hd l2) :: pair(tl l1, tl l2); 121} 122 123unpair[T1, T2](l: list of (T1, T2)): (list of T1, list of T2) 124{ 125 l1: list of T1; 126 l2: list of T2; 127 for(; l != nil; l = tl l){ 128 (v1, v2) := hd l; 129 l1 = v1 :: l1; 130 l2 = v2 :: l2; 131 } 132 return (reverse(l1), reverse(l2)); 133} 134 135ismember[T](x: T, l: list of T): int 136 for { T => eq: fn(a, b: T): int; } 137{ 138 for(; l != nil; l = tl l) 139 if(T.eq(x, hd l)) 140 return 1; 141 return 0; 142} 143