aboutsummaryrefslogtreecommitdiffhomepage
path: root/std/List.bruijn
diff options
context:
space:
mode:
Diffstat (limited to 'std/List.bruijn')
-rw-r--r--std/List.bruijn170
1 files changed, 133 insertions, 37 deletions
diff --git a/std/List.bruijn b/std/List.bruijn
index 44d833f..8683a43 100644
--- a/std/List.bruijn
+++ b/std/List.bruijn
@@ -60,19 +60,82 @@ index Z [[[case-some]]]
case-index =?1 ^0 (2 --1 ~0)
case-end empty
-(!!) C index
+(!!) \index
:test (((+1) : ((+2) : ((+3) : empty))) !! (+0)) ((+1))
:test (((+1) : ((+2) : ((+3) : empty))) !! (+2)) ((+3))
:test (((+1) : ((+2) : ((+3) : empty))) !! (-1)) (empty)
:test (((+1) : ((+2) : ((+3) : empty))) !! (+3)) (empty)
-# reverses a list
-reverse Z [[[case-some]]] case-empty
- case-some <>?0 case-end case-rev
- case-rev 2 (^0 : 1) ~0
+# applies a left fold on a list
+foldl Z [[[[case-some]]]]
+ case-some <>?0 case-end case-fold
+ case-fold 3 2 (2 1 ^0) ~0
case-end 1
- case-empty empty
+
+:test ((foldl add (+0) ((+1) : ((+2) : ((+3) : empty)))) =? (+6)) (true)
+:test ((foldl sub (+6) ((+1) : ((+2) : ((+3) : empty)))) =? (+0)) (true)
+
+# foldl without starting value
+foldl1 [[foldl 1 ^0 ~0]]
+
+# applies a right fold on a list
+foldr [[[Z [[case-some]] case-empty]]]
+ case-some <>?0 case-end case-fold
+ case-fold 4 ^0 (1 ~0)
+ case-end 3
+ case-empty 0
+
+:test ((foldr add (+0) ((+1) : ((+2) : ((+3) : empty)))) =? (+6)) (true)
+:test ((foldr sub (+2) ((+1) : ((+2) : ((+3) : empty)))) =? (+0)) (true)
+
+# foldr without starting value
+foldr1 [[foldl 1 ^0 ~0]]
+
+# applies or to all list elements
+lor? foldr or? false
+
+||( lor?
+
+:test (||(true : (true : empty))) (true)
+:test (||(true : (false : empty))) (true)
+:test (||(false : (false : empty))) (false)
+
+# applies and to all list elements
+land? foldr and? true
+
+&&( land?
+
+:test (&&(true : (true : empty))) (true)
+:test (&&(true : (false : empty))) (false)
+:test (&&(false : (false : empty))) (false)
+
+# multiplies all values in list
+product foldl mul (+1)
+
+Π product
+
+:test (Π ((+1) : ((+2) : ((+3) : empty)))) ((+6))
+
+# adds all values in list
+sum foldl add (+0)
+
+Σ sum
+
+:test (Σ ((+1) : ((+2) : ((+3) : empty)))) ((+6))
+
+# returns max value of list
+lmax foldl1 max
+
+:test (lmax ((+1) : ((+3) : ((+2) : empty)))) ((+3))
+
+# returns min value of list
+lmin foldl1 min
+
+:test (lmin ((+2) : ((+1) : ((+0) : empty)))) ((+0))
+
+# reverses a list
+reverse foldl \cons empty
<~>( reverse
@@ -110,32 +173,13 @@ map Z [[[case-some]]]
:test (inc <$> ((+1) : ((+2) : ((+3) : empty)))) ((+2) : ((+3) : ((+4) : empty)))
-# applies a left fold on a list
-foldl Z [[[[case-some]]]]
- case-some <>?0 case-end case-fold
- case-fold 3 2 (2 1 ^0) ~0
- case-end 1
-
-:test ((foldl add (+0) ((+1) : ((+2) : ((+3) : empty)))) =? (+6)) (true)
-:test ((foldl sub (+6) ((+1) : ((+2) : ((+3) : empty)))) =? (+0)) (true)
-
-# applies a right fold on a list
-foldr [[[Z [[case-some]] case-empty]]]
- case-some <>?0 case-end case-fold
- case-fold 4 ^0 (1 ~0)
- case-end 3
- case-empty 0
-
-:test ((foldr add (+0) ((+1) : ((+2) : ((+3) : empty)))) =? (+6)) (true)
-:test ((foldr sub (+2) ((+1) : ((+2) : ((+3) : empty)))) =? (+0)) (true)
-
# filters a list based on a predicate
filter Z [[[case-some]]]
case-some <>?0 case-end case-filter
case-filter 1 ^0 (cons ^0) I (2 1 ~0)
case-end empty
-(<#>) C filter
+(<#>) \filter
:test (((+1) : ((+0) : ((+3) : empty))) <#> zero?) ((+0) : empty)
@@ -157,6 +201,18 @@ init Z [[case-some]]
:test (init ((+1) : ((+2) : ((+3) : empty)))) ((+1) : ((+2) : empty))
+# concatenates a list of lists to one list
+concat foldr append empty
+
+# TODO: ?
+# :test (concat ((((+1) : ((+2) : empty)) : ((+3) : ((+4) : empty))) : empty)) ((+1) : ((+2) : ((+3) : ((+4) : empty))))
+:test (concat ("a" : ("b" : empty))) ("ab")
+
+# maps a function returning list of list and concatenates
+concat-map [foldr (append . 0) empty]
+
+:test (concat-map [-0 : (0 : empty)] ((+1) : ((+2) : empty))) ((-1) : ((+1) : ((-2) : ((+2) : empty))))
+
# zips two lists discarding excess elements
zip Z [[[case-some]]]
case-some <>?1 case-end case-zip
@@ -197,7 +253,7 @@ drop Z [[[case-some]]]
:test (drop (+2) ((+1) : ((+2) : ((+3) : empty)))) ((+3) : empty)
-# removes elements while a predicate is satisfied
+# removes elements from list while a predicate is satisfied
drop-while Z [[[case-some]]]
case-some <>?0 case-end case-drop
case-drop 1 ^0 (2 1 ~0) 0
@@ -205,7 +261,41 @@ drop-while Z [[[case-some]]]
:test (drop-while zero? ((+0) : ((+0) : ((+1) : empty)))) ((+1) : empty)
-# removes duplicates from list based on eq predicate (keeps only first occurrence)
+# returns true if any element in a list matches a predicate
+any? [lor? . (map 0)]
+
+:test (any? (\gre? (+2)) ((+1) : ((+2) : ((+3) : empty)))) (true)
+:test (any? (\gre? (+2)) ((+1) : ((+2) : ((+2) : empty)))) (false)
+
+# returns true if all elements in a list match a predicate
+all? [land? . (map 0)]
+
+:test (all? (\gre? (+2)) ((+3) : ((+4) : ((+5) : empty)))) (true)
+:test (all? (\gre? (+2)) ((+4) : ((+3) : ((+2) : empty)))) (false)
+
+# returns true if element is part of a list based on eq predicate
+in? [[any? (\1 0)]]
+
+:test (in? eq? (+3) ((+1) : ((+2) : ((+3) : empty)))) (true)
+:test (in? eq? (+0) ((+1) : ((+2) : ((+3) : empty)))) (false)
+
+# returns true if all elements of one list are equal to corresponding elements of other list
+# TODO: Better name
+leq? [[[land? (zip-with 2 1 0)]]]
+
+:test (leq? eq? ((+1) : ((+2) : empty)) ((+1) : ((+2) : empty))) (true)
+:test (leq? eq? ((+1) : ((+2) : empty)) ((+2) : ((+2) : empty))) (false)
+:test (leq? eq? empty empty) (true)
+
+# removes first element that match an eq predicate
+remove Z [[[[case-some]]]]
+ case-some <>?0 case-end case-remove
+ case-remove (2 ^0 1) ~0 (^0 : (3 2 1 ~0))
+ case-end empty
+
+:test (remove eq? (+2) ((+1) : ((+2) : ((+3) : ((+2) : empty))))) ((+1) : ((+3) : ((+2) : empty)))
+
+# removes duplicates from list based on eq predicate (keeps first occurrence)
nub Z [[[case-some]]]
case-some <>?0 case-end case-nub
case-nub ^0 : (2 1 (~0 <#> [!(2 0 ^1)]))
@@ -214,20 +304,26 @@ nub Z [[[case-some]]]
:test (nub eq? ((+1) : ((+2) : ((+3) : empty)))) (((+1) : ((+2) : ((+3) : empty))))
:test (nub eq? ((+1) : ((+2) : ((+1) : empty)))) (((+1) : ((+2) : empty)))
+# returns a list with infinite-times a element
+repeat Z [[case-some]]
+ case-some 0 : (1 0)
+
+:test (take (+3) (repeat (+4))) ((+4) : ((+4) : ((+4) : empty)))
+
# returns a list with n-times a element
-repeat Z [[[case-some]]]
- case-some =?1 case-end case-repeat
- case-repeat 0 : (2 --1 0)
- case-end empty
+replicate [[take 1 (repeat 0)]]
+
+:test (replicate (+3) (+4)) ((+4) : ((+4) : ((+4) : empty)))
+
+# returns an infinite list repeating a finite list
+cycle Z [[case-some]]
+ case-some 0 ++ (1 0)
-:test (repeat (+5) (+4)) (((+4) : ((+4) : ((+4) : ((+4) : ((+4) : empty))))))
-:test (repeat (+1) (+4)) (((+4) : empty))
-:test (repeat (+0) (+4)) (empty)
+:test (take (+6) (cycle "ab")) ("ababab")
# returns a list with infinite-times previous (or start) value applied to a function
iterate Z [[[case-some]]]
- case-some case-iterate
- case-iterate 0 : (2 1 (1 0))
+ case-some 0 : (2 1 (1 0))
:test (take (+5) (iterate inc (+0))) (((+0) : ((+1) : ((+2) : ((+3) : ((+4) : empty))))))
:test (take (+2) (iterate dec (+5))) (((+5) : ((+4) : empty)))