|
| 1 | +# scott-lists.lc |
| 2 | + |
| 3 | +#import combinators.lc |
| 4 | +B = \ f g x . f (g x) |
| 5 | +BB = \ f g x y . f (g x y) |
| 6 | +CB = \ f g x . g (f x) |
| 7 | +C = \ f x y . f y x |
| 8 | +I = \ x . x |
| 9 | +K = \ x _ . x |
| 10 | +KI = \ _ x . x |
| 11 | +KK = \ x _ _ . x |
| 12 | +M = \ x . x x |
| 13 | +S = \ f g x . f x (g x) |
| 14 | +T = \ x fn . fn x |
| 15 | +V = \ x y fn . fn x y |
| 16 | +W = \ f x . f x x |
| 17 | +#import scott-booleans.ls |
| 18 | +False = K |
| 19 | +True = KI |
| 20 | +not = \ p . p True False |
| 21 | +and = M |
| 22 | +or = W C |
| 23 | +#import scott-ordering.lc |
| 24 | +LT = KK |
| 25 | +EQ = K K |
| 26 | +GT = K KI |
| 27 | +#import scott-numbers.lc |
| 28 | +zero = K |
| 29 | +succ = \ n . \ _zero succ . succ n |
| 30 | +pred = \ n . n zero I |
| 31 | +add = \ m n . m n (B succ (add n)) |
| 32 | +sub = \ m n . m m (B (n m) sub) |
| 33 | +mul = \ m n . m m (B (add n) (mul n)) |
| 34 | +is-zero = \ n . n True (K False) |
| 35 | +one = succ zero |
| 36 | +#import scott-pair.lc |
| 37 | +Pair = V |
| 38 | +fst = T K |
| 39 | +snd = T KI |
| 40 | +first = \ fn xy . xy \ x . Pair (fn x) |
| 41 | +second = \ fn xy . xy \ x y . Pair x (fn y) |
| 42 | +both = \ fn xy . xy \ x y . Pair (fn x) (fn y) |
| 43 | +bimap = \ f g xy . xy \ x y . Pair (f x) (g y) |
| 44 | +curry fn x y = fn (Pair x y) |
| 45 | +uncurry = T |
| 46 | +#import scott-option.lc |
| 47 | +None = K # = zero |
| 48 | +Some = \ x . \ _none some . some x # = succ |
| 49 | +option = V |
| 50 | +is-none = \ x . x True (K False) # = is-zero |
| 51 | +is-some = \ x . x False (K True) |
| 52 | +from-option = \ z x . x z I |
| 53 | +from-some = \ x . x () I |
| 54 | +list-to-option = \ xs . xs None \ x _xs . Some x |
| 55 | +option-to-list = \ x . x nil singleton |
| 56 | +map-option = \ fn xs . xs nil \ x xs . fn x (map-options fn xs) (C cons (map-options fn xs)) |
| 57 | +cat-options = map-options I |
| 58 | + |
| 59 | +# data List a = Nil | Cons a (List a) |
| 60 | + |
| 61 | +# nil :: List a |
| 62 | +nil = K |
| 63 | + |
| 64 | +# cons :: a -> List a -> List a |
| 65 | +cons = \ x xs . \ _nil cons . cons x xs |
| 66 | + |
| 67 | +# singleton :: a -> List a |
| 68 | +singleton = \ x . cons x nil |
| 69 | + |
| 70 | +# foldr :: (a -> z -> z) -> z -> List a -> z |
| 71 | +foldr = \ fn z xs . xs z ( \ x xs . fn x (foldr fn z xs) ) |
| 72 | + |
| 73 | +# null :: List a -> Boolean |
| 74 | +null = \ xs . xs True (KK False) |
| 75 | + |
| 76 | +# take :: Number -> List a -> List a |
| 77 | +take = \ n xs . is-zero n (xs nil \ x xs . cons x (take (pred n) xs)) nil |
| 78 | + |
| 79 | +# append :: List a -> List a -> List a |
| 80 | +append = C (foldr cons) |
| 81 | + |
| 82 | +# concat :: List (List a) -> List a |
| 83 | +concat = \ xss . foldr xss append nil |
| 84 | + |
| 85 | +# sum,product :: List Number -> Number |
| 86 | +sum = foldr add zero |
| 87 | +product = foldr mul one |
| 88 | + |
| 89 | +# iterate :: (a -> a) -> a -> List a |
| 90 | +iterate = \ fn x . cons x (iterate fn (fn x)) |
| 91 | + |
| 92 | +# repeat :: a -> List a |
| 93 | +repeat = \ x . cons x (repeat x) # repeat = Y (S cons) |
| 94 | + |
| 95 | +# cycle :: List a -> List a |
| 96 | +cycle = \ xs . null xs (concat (repeat xs)) () |
| 97 | + |
| 98 | +# replicate :: Number -> a -> List a |
| 99 | +replicate = \ n . B (take n) repeat |
| 100 | + |
| 101 | +# head :: List a -> a |
| 102 | +head = \ xs . xs () K |
| 103 | + |
| 104 | +# tail :: List a -> List a |
| 105 | +tail = \ xs . xs () KI |
| 106 | + |
| 107 | +# length :: List a -> Number |
| 108 | +length = foldr (K succ) zero |
| 109 | + |
| 110 | +# snoc :: List a -> a -> List a |
| 111 | +snoc = C (B (foldr cons) singleton) |
| 112 | + |
| 113 | +# map :: (a -> b) -> List a -> List b |
| 114 | +map = \ fn . foldr (B cons fn) nil |
| 115 | + |
| 116 | +# concat-map :: (a -> List b) -> List a -> List b |
| 117 | +concat-map = BB concat map |
| 118 | + |
| 119 | +# filter :: () -> List a -> List a |
| 120 | +filter = \ p . foldr ( \ x z . p x z (cons x z) ) nil |
| 121 | +filter = \ p . foldr ( \ x . S (p x) (cons x) ) nil |
| 122 | +filter = \ p . foldr (S (B S p) cons) nil |
| 123 | + |
| 124 | +# drop :: Number -> List a -> List a |
| 125 | +drop = \ n xs . is-zero n ( \ _x xs . drop (pred n) xs ) xs |
| 126 | +drop = \ n . is-zero n (K (drop (pred n))) |
| 127 | + |
| 128 | +# split-at :: Number -> List a -> Pair (List a) (List a) |
| 129 | +split-at = \ i xs . is-zero i (xs (Pair nil nil) \ x xs . first (cons x) (split-at (pred i) xs)) (Pair nil xs) |
| 130 | + |
| 131 | +# get :: Number -> List a -> a |
| 132 | +get = \ i xs . is-zero i ( \ x xs . xs () (get (pred i) xs) ) (head xs) |
| 133 | + |
| 134 | +# set :: Number -> a -> List a -> List a |
| 135 | +set = \ i x xs . uncurry append (second (B (cons x) tail) (split-at i xs)) |
| 136 | +set = \ i x xs . is-zero i (xs nil \ y ys . cons y (set (pred i) x ys)) (xs nil (K (cons x))) |
| 137 | + |
| 138 | +# any :: (a -> Boolean) -> List a -> Boolean |
| 139 | +any = \ p . foldr (B or p) False |
| 140 | + |
| 141 | +# all :: (a -> Boolean) -> List a -> Boolean |
| 142 | +all = \ p . foldr (B and p) True |
| 143 | + |
| 144 | +# find :: (a -> Boolean) -> List a -> Option a |
| 145 | +find = \ p . foldr ( \ x z . p x z (Some x) ) None |
| 146 | + |
| 147 | +# find-index :: (a -> Boolean) -> List a -> Option Number |
| 148 | +find-index p = B list-to-option (find-indices p) |
| 149 | + |
| 150 | +# find-indices :: (a -> Boolean) -> List a -> List Number |
| 151 | +find-indices p = foldr ( \ x k i . p x I (cons i) (k (succ i)) ) (K nil) zero |
| 152 | + |
| 153 | +# partition :: (a -> Boolean) -> List a -> Pair (List a) (List a) |
| 154 | +partition = \ p . foldr ( \ x . p x second first (cons x) ) (Pair nil nil) |
| 155 | + |
| 156 | +# span :: (a -> Boolean) -> List a -> Pair (List a) (List a) |
| 157 | +span = \ p xs . xs (Pair nil nil) \ y ys . p y (Pair nil xs) (first (cons y) (span p ys)) |
| 158 | + |
| 159 | +# minimum-by :: (a -> a -> Boolean) -> List a -> a # cmp ~ le |
| 160 | +minimum-by = \ cmp xs . xs () (foldr \ x z . cmp x z z x) |
| 161 | + |
| 162 | +# maximum-by :: (a -> a -> Boolean) -> List a -> a # cmp ~ le |
| 163 | +maximum-by = \ cmp xs . xs () (foldr \ x z . cmp x z x z) |
| 164 | + |
| 165 | +# insert-by :: (a-> a -> Boolean) -> a -> List a -> List a # cmp ~ le |
| 166 | +insert-by = \ cmp x xs . uncurry append (second (cons x) (span (C cmp x) xs)) |
| 167 | + |
| 168 | +# sort-by :: (a -> a -> Boolean) -> List a -> List a # cmp ~ le |
| 169 | +sort-by = \ cmp . foldr (insert-by cmp) nil |
| 170 | + |
| 171 | +# foldl :: (z -> a -> z) -> z -> List a -> z |
| 172 | +foldl = \ fn z xs . xs z (B (foldl fn) (fn z)) |
| 173 | + |
| 174 | +# scanl :: (z -> a -> z) -> z -> List a -> List z |
| 175 | +scanl = \ fn z xs . cons z (xs nil (B (scanl fn) (fn z))) |
| 176 | + |
| 177 | +# scanr :: (a -> z -> z) -> z -> List a -> List z |
| 178 | +scanr = \ fn z xs . xs (singleton z) \ x xs . ( \ zs . zs \ z _zs . cons (fn x z) zs ) (scanr fn z xs) |
| 179 | + |
| 180 | +# reverse :: List a -> List a |
| 181 | +reverse = foldl (C cons) nil |
| 182 | + |
| 183 | +# init :: List a -> List a |
| 184 | +init = \ xs . xs () (S (zip-with K) tail xs) |
| 185 | + |
| 186 | +# last :: List a -> a |
| 187 | +last = foldl KI () |
| 188 | + |
| 189 | +# unzip :: List (Pair a b) -> Pair (List a) (List b) |
| 190 | +unzip = foldr ( \ xy xys . xy \ x y . bimap (cons x) (cons y) xys ) (Pair nil nil) |
| 191 | +unzip = foldr (CB \ x y . bimap (cons x) (cons y)) (Pair nil nil) |
| 192 | + |
| 193 | +# zip-with :: (a -> b -> z) -> List a -> List b -> List z |
| 194 | +zip-with = \ fn xs ys . xs nil \ x xs . ys nil \ y ys . cons (fn x y) (zip-with fn xs ys) |
| 195 | + |
| 196 | +# zip :: List a -> List b -> List (Pair a b) |
| 197 | +zip = zip-with Pair |
| 198 | + |
| 199 | +# slice :: Number -> Number -> List a -> List a |
| 200 | +slice = \ i j xs . gt j i nil (take (sub j i) (drop i xs)) |
| 201 | + |
| 202 | +# uncons :: List a -> Option (Pair (a) (List a)) |
| 203 | +uncons = \ xs . xs None (B Some Pair) |
| 204 | + |
| 205 | +# transpose :: List (List a) -> List (List a) |
| 206 | +transpose = \ xss . xss nil |
| 207 | + \ ys yss . ys (transpose yss) |
| 208 | + (unzip (map-option uncons xss) \ xs xxs . cons xs (transpose xss)) |
| 209 | + |
| 210 | +# unfold :: (a -> Option (Pair z a)) -> a -> List z |
| 211 | +unfold = \ fn x . fn x nil (T \ z x . cons z (unfold fn x)) |
| 212 | + |
| 213 | +# take-while :: (a -> Boolean) -> List a -> List a |
| 214 | +take-while = \ p xs . xs nil \ x xs . p x nil (cons x (take-while p xs)) |
| 215 | + |
| 216 | +# drop-while :: (a -> Boolean) -> List a -> List a |
| 217 | +drop-while = \ p xs . xs nil \ x xs . p x xs (drop-while p xs) |
| 218 | + |
| 219 | +# drop-while-end :: (a -> Boolean) -> List a -> List a |
| 220 | +drop-while-end = \ p . foldr ( \ x z . and (null z) (p x) (cons x z) nil ) nil |
| 221 | + |
| 222 | +# group-by :: (a -> a -> Bool) -> List a -> List (List a) |
| 223 | +group-by = \ eq xs . xs nil \ x xs . span (eq x) xs \ left right . cons (cons x left) (group-by eq right) |
| 224 | +group-by = \ eq xs . xs nil \ x xs . uncurry cons (bimap (cons x) (group-by eq) (span (eq x) xs)) |
| 225 | + |
| 226 | +# inits |
| 227 | + |
| 228 | +# tails :: List a -> List (List a) |
| 229 | +tails = \ xs . cons xs (xs nil (K tails)) |
| 230 | + |
| 231 | +# lookup-by :: (a -> Boolean) -> List (Pair a b) -> Option b |
| 232 | +lookup-by = \ eq xys . xys None \ xy xys . xy \ x y . eq x (lookup-by eq xys) (Some y) |
| 233 | + |
| 234 | +# nub-by |
| 235 | +# delete-by |
| 236 | +# delete-firsts-by |
| 237 | +# sort-on |
0 commit comments