diff options
Diffstat (limited to 'desk/lib/seq.hoon')
-rw-r--r-- | desk/lib/seq.hoon | 1809 |
1 files changed, 1809 insertions, 0 deletions
diff --git a/desk/lib/seq.hoon b/desk/lib/seq.hoon new file mode 100644 index 0000000..12f8d26 --- /dev/null +++ b/desk/lib/seq.hoon @@ -0,0 +1,1809 @@ +:: /lib/seq/hoon +:: |seq +:: operations for working with values of type list +:: +|% +:: +all-pairs: [(list T1) (list T2)] -> (list [T1 T2]) +:: +:: Returns a new list that contains all pairings of elements from two non-empty +:: lists. +:: Examples +:: > (all-pairs ~['a' 'b' 'c'] ~[1 2 3]) +:: ~[['c' 3] ['c' 2] ['c' 1] +:: ['b' 3] ['b' 2] ['b' 1] +:: ['a' 3] ['a' 2] ['a' 1]] +:: Source +++ all-pairs + |* [p=(list) q=(list)] + =/ a=(list _?>(?=(^ p) i.p)) p + =/ res=(list [_?>(?=(^ p) i.p) _?>(?=(^ q) i.q)]) ~ + =/ scnd=(list _?>(?=(^ q) i.q)) q + |- ^- (list [_?>(?=(^ p) i.p) _?>(?=(^ q) i.q)]) + ?~ a res + ?~ scnd $(a t.a, scnd q) + $(res [[i.a i.scnd] res], scnd +.scnd) +:: +append: [(list) (list)] -> (list) +:: +:: Returns a new list that contains the elements of the first list followed by +:: elements of the second list. +:: Examples +:: > (append "urb" "it") +:: "urbit" +:: > (append (limo [1 2 ~]) (limo [3 4 ~])) +:: ~[1 2 3 4] +:: Source +++ append weld +:: +average: (list @) -> @ud +:: +:: Returns the average of the values in a non-empty list. +:: Examples +:: > (average `(list @ud)`~[1 2 3 4]) +:: 2 +:: Source +++ average + |* a=(list @) + (div (roll a add) (lent a)) +:: +average-by: [(list T) projection:$-(T @ud)] -> @ud +:: +:: Returns the average of values in a list generated by applying a function to +:: each element of the list. +:: Examples +:: > (average-by (limo ~[[1 1] [2 2] [3 3] [4 4]]) |=([a=@ b=@] (add a b))) +:: 5 +:: Source +++ average-by + |* [a=(list) b=$-(* @ud)] + (div (roll (turn a b) add) (lent a)) +:: +choose: [(list T1) $-(T1 (unit T2))] -> (list T2) +:: +:: Applies a function to each element in a list and then returns a list of +:: values v where the applied function returns (unit v). +:: Returns an empty list when the input list is empty or when the applied +:: chooser function returns ~ for all elements. +:: Examples +:: > =a |=(a=@ ?.((gte a 2) ~ (some (add a 10)))) +:: > (choose `(list @)`[0 1 2 3 ~] a) +:: [i=12 t=[i=13 t=~]] +:: Source +++ choose murn +:: +chunk-by-size: [(list T) chunkSize:@] -> (list (list T)) +:: +:: Divides the input list into lists (chunks) with a positive number of at +:: most chunkSize elements. Returns a new list containing the generated lists +:: (chunks) as its elements. Returns an empty list when the input list is empty +:: Examples +:: > (chunk-by-size (limo ~[1 2 3 4 5 6 7]) 2) +:: [i=~[1 2] t=[i=~[3 4] t=~[~[5 6] ~[7]]]] +:: Crash +:: 'chunk size is 0' +:: Source +++ chunk-by-size + |* [p=(list) q=@ud] + ?: =(0 q) ~|('chunk size is 0' !!) + =/ res=(list (list _?>(?=(^ p) i.p))) ~ + =/ i=@ud 0 + =/ next=(list _?>(?=(^ p) i.p)) ~ + |- ^- (list (list _?>(?=(^ p) i.p))) + ?~ p (flop [(flop next) res]) + ?: =(i q) $(i 0, res [(flop next) res], next ~) + $(i +(i), next [i.p next], p t.p) +:: +collect: [(list T1) mapping:$-(T1 (list T2))] -> (list T2) +:: +:: For each element of the list, applies the given function. Concatenates all +:: the results and return the combined list. +:: Examples +:: > (collect (limo ~[1 2 3]) |=(a=* (limo ~[a a]))) +:: ~[1 1 2 2 3 3] +:: Source +++ collect + |* [p=(list) q=$-(* (list))] + =/ res=(list) ~ + |- + ?~ p (flop res) + =/ c=(list) (q i.p) + |- + ?~ c ^$(p t.p) + $(c t.c, res [i.c res]) +:: +compare: [(list T) (list T) comparer:$-([T T] ?)] -> (list ?) +:: +:: Compares two lists element by element using the given comparison function. +:: When an entry exists for both lists, returns the result of the comparer +:: function. When the second list is longer than the first returns %.y for +:: entries of second where first does not exist. When first list is longer +:: returns %.n for entries of first where second does not exist. +:: Examples +:: > (compare "when" "than" aor) +:: ~[%.n %.y %.n %.y] +:: Source +++ compare + |* [b=(list) c=(list) a=$-([* *] ?)] + =/ res=(list ?) ~ + =/ bb b + =/ cc c + |- ^- (list ?) + ?~ bb ?~ cc (flop res) $(cc t.cc, res [%.y res]) + ?~ cc $(bb t.bb, res [%.n res]) + $(bb t.bb, cc t.cc, res [(a i.bb i.cc) res]) +:: +concat: (list (list)) -> (list) +:: +:: Returns a new list that contains the elements of each of the lists in order. +:: Examples +:: > (concat (limo [(limo ['a' 'b' 'c' ~]) (limo ['e' 'f' 'g' ~]) +:: (limo ['h' 'i' 'j' ~]) ~])) +:: ~['a' 'b' 'c' 'e' 'f' 'g' 'h' 'i' 'j'] +:: > (concat (limo [(limo [1 'a' 2 'b' ~]) (limo [3 'c' 4 'd' ~]) ~])) +:: ~[1 97 2 98 3 99 4 100] +:: Source +++ concat zing +:: +contains: [(list) value:*] -> ? +:: +:: Tests if the list contains the specified element. +:: Examples +:: > (contains "yep" `(list tape)`~["nope" "yep"]) +:: %.y +:: Source +++ contains + |* [p=(list) q=*] + |- ^- ? + ?~ p %.n + ?: =(q i.p) %.y + $(p t.p) +:: +count-by: [(list T1) projection:$-(T1 T2)] -> (list [T2 @ud]) +:: +:: Applies a key-generating function to each element of a list and returns a +:: list yielding unique keys and their number of occurrences in the original +:: list. +:: Examples +:: > %: count-by +:: (limo ~["where" "when" "there" "then"]) +:: |=(a=tape (scag 2 a)) +:: == +:: ~[[[i=t' t="h"] 2] [[i='w' t="h"] 2]] +:: Source +++ count-by + |* [p=(list) q=$-(* *)] + =/ res=(map _?>(?=(^ p) (q i.p)) @ud) ~ + |- ^- (list [_?>(?=(^ p) (q i.p)) @ud]) + ?~ p ~(tap by res) + =/ key=_?>(?=(^ p) (q i.p)) (q i.p) + =/ val (~(get by res) key) + ?~ val $(res `(map _?>(?=(^ p) (q i.p)) @ud)`(~(put by res) key 1), p t.p) + %= $ + res `(map _?>(?=(^ p) (q i.p)) @ud)`(~(put by res) key +(`@ud`(need val))) + p t.p + == +:: +distinct: (list) -> (list) +:: +:: Returns a list that contains no duplicate entries according to generic hash +:: and equality comparisons on the entries. If an element occurs multiple times +:: in the list then the later occurrences are discarded. +:: Examples +:: > (distinct `(list tape)`~["tape1" "tape0" "tape1" "tape0"]) +:: ~["tape1" "tape0"] +:: Source +++ distinct + |* a=(list) + =/ b=(list _?>(?=(^ a) i.a)) ~ + =/ c=(set) ~ + |- ^+ a + ?~ a (flop b) + ?: (~(has in c) i.a) $(a t.a) + $(a t.a, b [i.a b], c (~(put in c) i.a)) +:: +distinct-by: [(list T1) projection:$-(T1 T2)] -> (list T1) +:: +:: Returns a list that contains no duplicate entries according to the generic +:: hash and equality comparisons on the keys returned by the given +:: key-generating function. If an element occurs multiple times in the list +:: then the later occurrences are discarded. +:: Examples +:: > =foo `(list [@ @])`~[[1 1] [1 2] [1 3] [2 1]] +:: > (distinct-by foo |=([a=@ b=@] (add a b))) +:: ~[[1 1] [1 2] [1 3]] +:: Source +++ distinct-by + |* [p=(list) q=$-(* *)] + =/ b=(list _?>(?=(^ p) i.p)) ~ + =/ c=(set) ~ + |- ^+ p + ?~ p (flop b) + ?: (~(has in c) (q i.p)) $(p t.p) + $(p t.p, b [i.p b], c (~(put in c) (q i.p))) +:: +empty: $ -> *(list $) +:: +:: Returns an empty list typed by the mold. (The bunt of the typed list.) +:: Examples +:: > (empty @t) +:: ~ +:: Source +++ empty + |* a=mold + *(list a) +:: +exactly-one: (list T) -> T +:: +:: Returns the only element of the list. Crashes if list has different length. +:: Examples +:: > (exactly-one (limo ~["tape"])) +:: "tape" +:: Crash +:: 'list length is not 1' +:: Source +++ exactly-one + |* a=(list) + ?: =(1 (lent a)) -.a + ~|('list length is not 1' !!) +:: +except: [(list T) items-to-exclude:(list T)] -> (list T) +:: +:: Returns a new list with the distinct elements of the input list which do not +:: appear in the items-to-exclude list, using generic hash and equality +:: comparisons to compare values. +:: Examples +:: > %: except +:: (limo ~["able" "baker" "charlie" "dog"]) +:: (limo ~["baker" "dog"]) +:: == +:: ~[[i='a' t="ble"] [i='c' t="harlie"]] +:: Source +++ except + |* [p=(list) q=(list)] + =/ qq (silt q) + =/ b=(list _?>(?=(^ p) i.p)) ~ + |- ^+ p + ?~ p (flop b) + ?: (~(has in qq) i.p) $(p t.p) + $(p t.p, b [i.p b], qq (~(put in qq) i.p)) +:: +exists: [(list T) predicate:$-(T ?)] -> ? +:: +:: Tests if any element of the list satisfies the given predicate. +:: Examples +:: > =foo |= a=tape +:: ?: ?&(=(4 (lent a)) =('a' -.a)) %.y %.n +:: > (exists (limo ~["aaa" "able" "baker" "charlie" "dog"]) foo) +:: %.y +:: Source +++ exists + |* [a=(list) b=$-(* ?)] + |- ^- ? + ?~ a %.n + ?: (b i.a) %.y + $(a t.a) +:: +exists2: [(list T1) (list T2) predicate:$-([T1 T2] ?)] -> ? +:: +:: Tests if any pair of corresponding elements of the lists satisfies the given +:: predicate. +:: Examples +:: > =foo |= [a=tape b=tape] +:: ?: =(-.a -.b) %.y %.n +:: > (exists2 (limo ~["cat" "betty"]) (limo ~["able" "butter"]) foo) +:: %.y +:: Source +++ exists2 + |* [a=(list) b=(list) c=$-([* *] ?)] + |- ^- ? + ?~ a %.n + ?~ b %.n + ?: (c [i.a i.b]) %.y + $(a t.a, b t.b) +:: +filter: [(list T) predicate:$-(T ?)] -> (list T) +:: +:: Returns a new list containing only the elements of the list for +:: which the given predicate returns "true" +:: Examples +:: > =a |=(a=@ (gth a 1)) +:: > (filter `(list @)`[0 1 2 3 ~] a) +:: [i=2 t=~[3]] +:: Source +++ filter skim +:: +:: +findx: [(list T) predicate:$-(T ?)] -> T +:: +:: Returns the first element for which the given function returns True. +:: Crashes if no such element exists. +:: Examples +:: > (findx (gulf [1 30]) |=(a=@ud ?&(=(0 (mod a 3)) =(0 (mod a 5))))) +:: 15 +:: Crash +:: 'not found' +:: Source +++ findx + |* [a=(list) b=$-(* ?)] + |- ^- _?>(?=(^ a) i.a) + ?~ a ~|('not found' !!) + ?: (b i.a) i.a $(a t.a) +:: +find-all: [(list T) predicate:$-(T ?)] -> (list T)) +:: +:: Returns all elements for which the given function returns True. +:: Crashes if no such element exists. +:: Examples +:: > (find-all (gulf [1 30]) |=(a=@ud ?&(=(0 (mod a 3)) =(0 (mod a 5))))) +:: ~[15 30] +:: Crash +:: 'not found' +:: Source +++ find-all + |* [a=(list) b=$-(* ?)] + =/ c=(list _?>(?=(^ a) i.a)) ~ + |- + ?~ a ?~ c ~|('not found' !!) (flop c) + ?: (b i.a) $(a t.a, c [i.a c]) $(a t.a) +:: +find-all-by-list: [(list T) arg:(list T) -> (list @)] +:: +:: Produces list of indices of all occurrences of the argument list sequence in +:: the sequence of the source list. +:: Examples +:: > (find-all-by-list "cbabab" "ba") +:: ~[1 3] +:: Source +++ find-all-by-list + |* [hstk=(list) nedl=(list)] + ^- (list @) + (fand nedl hstk) +:: +find-all-by-unit: [(list T1) chooser:$-(T1 (unit T2))] -> (list T2) +:: +:: Applies the given function to successive elements, returning the list of +:: elements where the function returns Some(x). +:: Crashes when no such element exists. +:: Examples +:: > %: find-all-by-unit +:: (limo ~[1 2 3 4]) +:: |=(a=@ ?:(=((mod a 2) 0) `a ~)) +:: == +:: ~[2 4] +:: Crash +:: 'not found' +:: Source +++ find-all-by-unit + |* [hstk=(list) nedl=$-(* (unit *))] + =/ b=(list _?>(?=(^ hstk) i.hstk)) ~ + |- ^- (list _?>(?=(^ hstk) i.hstk)) + ?~ hstk ?~ b ~|('not found' !!) + (flop b) + =/ x (nedl i.hstk) + ?~ x $(hstk t.hstk) + $(hstk t.hstk, b [(need x) b]) +:: +find-back: [(list T) predicate:$-(T ?)] -> T +:: +:: Returns the last element for which the given function returns True. +:: Crashes if no such element exists. +:: Examples +:: > %: find-back +:: (gulf [1 30]) +:: |=(a=@ud ?&(=(0 (mod a 3)) =(0 (mod a 5)))) +:: == +:: 30 +:: Crash +:: 'not found' +:: Source +++ find-back + |* [a=(list) b=$-(* ?)] + ?~ a ~|('not found' !!) + (findx (flop a) b) +:: +find-back-by-list: [(list T) arg:(list T)] -> @ +:: +:: Produces the index of the last occurrence of the argument list sequence in +:: the sequence of the source list. +:: Examples +:: > (find-back-by-list "cbabab" "ba") +:: 3 +:: Source +++ find-back-by-list + |* [hstk=(list) nedl=(list)] + (tail-end (find-all-by-list hstk nedl)) +:: +find-back-by-unit: [(list T1) chooser:$-(T1 (unit T2))] -> T2 +:: +:: Applies the given function to successive elements from the end back, +:: returning the first result where function returns Some(x) for some x. +:: Crashes when no such element exists. +:: Examples +:: > %: find-back-by-unit +:: (limo ~[1 2 3 4]) +:: |=(a=@ ?:(=((mod a 2) 0) `a ~)) +:: == +:: 4 +:: Crash +:: 'not found' +:: Source +++ find-back-by-unit + |* [hstk=(list) nedl=$-(* (unit *))] + ^- _?>(?=(^ hstk) i.hstk) + (find-by-unit (flop hstk) nedl) +:: +find-by-list: [(list T) arg:(list T)] -> @ +:: +:: Produces the index of the first occurrence of the argument list sequence in +:: the sequence of the source list. +:: Examples +:: > (find-by-list "cbabab" "ab") +:: 2 +:: Crash +:: 'not found' +:: Source +++ find-by-list + |* [hstk=(list) nedl=(list)] + ^- @ + =/ x (find nedl hstk) + ?~ x ~|('not found' !!) (need x) +:: +find-by-unit: [(list T1) chooser:$-(T1 (unit T2))] -> T2 +:: +:: Applies the given function to successive elements, returning the first +:: result where function returns Some(x) for some x. Crashes when no such +:: element exists. +:: Examples +:: > (find-by-unit (limo ~[1 2 3 4]) |=(a=@ ?:(=((mod a 2) 0) `a ~))) +:: 2 +:: Crash +:: 'not found' +:: Source +++ find-by-unit + |* [hstk=(list) nedl=$-(* (unit *))] + |- ^- _?>(?=(^ hstk) i.hstk) + ?~ hstk ~|('not found' !!) + =/ x (nedl i.hstk) + ?~ x $(hstk t.hstk) + (need x) +:: +find-index: [(list T) predicate:$-(T ?)] -> @ +:: +:: Returns the index of the first element in the list that satisfies the given +:: predicate. Crashes if no such element exists. +:: Examples +:: > %: find-index +:: (gulf [1 30]) +:: |=(a=@ud ?&(=(0 (mod a 3)) =(0 (mod a 5)))) +:: == +:: 14 +:: Crash +:: 'not found' +:: Source +++ find-index + |* [a=(list) b=$-(* ?)] + =/ i 0 + |- ^- @ + ?~ a ~|('not found' !!) + ?: (b i.a) i $(a t.a, i +(i)) +:: +find-index-all: [(list T) predicate:$-(T ?)] -> (list @) +:: +:: Returns the list of indices in the list that satisfies the given predicate. +:: Examples +:: > %: find-index-all +:: (gulf [1 30]) +:: |=(a=@ud ?&(=(0 (mod a 3)) =(0 (mod a 5)))) +:: == +:: ~[14 29] +:: Source +++ find-index-all + |* [a=(list) b=$-(* ?)] + =/ c=(list @) ~ + =/ i 0 + |- ^- (list @) + ?~ a (flop c) + ?: (b i.a) $(a t.a, c [i c], i +(i)) $(a t.a, i +(i)) +:: +find-index-back: [(list T) predicate:$-(T ?)] -> @ +:: +:: Returns the index of the last element in the list that satisfies the given +:: predicate. Crashes if no such element exists. +:: Examples +:: > %: find-index-back +:: (gulf [1 30]) +:: |=(a=@ud ?&(=(0 (mod a 3)) =(0 (mod a 5)))) +:: == +:: 29 +:: Crash +:: 'not found' +:: Source +++ find-index-back + |* [a=(list) c=$-(* ?)] + ?~ a ~|('not found' !!) + =/ b (flop a) + =/ i (dec (lent a)) + |- ^- @ud + ?~ b ~|('not found' !!) + ?: (c i.b) i + ?: =(0 i) ~|('not found' !!) + $(b t.b, i (dec i)) +:: +first-n: [(list T) count:@ud] -> (list T) +:: +:: Returns the first N elements of the list. +:: Examples +:: > (first-n `(list @)`[1 2 3 4 ~] 2) +:: [i=1 t=~[2]] +:: > (first-n `(list @)`[1 2 3 4 ~] 10) +:: [i=1 t=~[2 3 4]] +:: Source +++ first-n + |* [p=(list) q=@] + (scag q p) +:: +fold: [(list T1) state:T2 folder:$-([T1 T2] T2)] -> T2 +:: +:: Applies a function to each element of the list, threading an +:: accumulator argument through the computation. Take the second argument, and +:: apply the function to it and the first element of the list. Then feed this +:: result into the function along with the second element and so on. Return the +:: final result. If the input function is f and the elements are i0...iN then +:: computes f (... (f s i0) i1 ...) iN. +:: Examples +:: > (fold (gulf 1 5) 0 |=([n=@ state=@] (add state (mul n n)))) +:: 55 +:: Source +++ fold + |* [a=(list) b=* c=_|=(^ [** +<+])] + |- ^- _b + ?~ a b + $(a t.a, b (c i.a b)) +:: +fold2: [(list T1) (list T2) state:T3 folder:$-([T1 T2 T3] T3)] -> T3 +:: +:: Applies a function to corresponding elements of two lists, threading +:: an accumulator argument through the computation. The lists must have +:: identical sizes. If the input function is f and the elements are i0...iN and +:: j0...jN then computes f (... (f s i0 j0)...) iN jN. +:: Examples +:: > %: fold2 +:: (limo ~["Tails" "Head" "Tails"]) +:: (limo ~["Tails" "Head" "Head"]) +:: 0 +:: |=([n1=tape n2=tape state=@] ?:(=(n1 n2) +(state) state)) +:: == +:: 2 +:: Crash +:: 'lists of unequal length' +:: Source +++ fold2 + |* [a=(list) b=(list) c=* d=_|=(^ [** ** +<+])] + |- ^- _c + ?~ a ?~ b c ~|('lists of unequal length' !!) + ?~ b ~|('lists of unequal length' !!) + $(a t.a, b t.b, c (d i.a i.b c)) +:: +fold-back: [(list T1) state:T2 folder:$-([T1 T2] T2)] -> T2 +:: +:: Applies a function to each element of the list, starting from the end, +:: threading an accumulator argument through the computation. If the input +:: function is f and the elements are i0...iN then computes f i0 (...(f iN s)). +:: Examples +:: > =less-hungry |= [n=tape state=(list [tape @])] +:: ^+ state +:: ?~ state (limo ~[[n 1]]) +:: [[n +(+.i.state)] state] +:: > %: fold-back +:: (limo ~["Apple" "Pear" "Orange"]) +:: `(list [tape @])`~ +:: less-hungry +:: == +:: [i=["Apple" 3] t=~[["Pear" 2] ["Orange" 1]]] +:: Source +++ fold-back + |* [a=(list) b=* c=$-([* *] *)] + (fold (flop a) b c) +:: +fold-back2: [(list T1) (list T2) state:T3 folder:$-([T1 T2 T3] T3)] -> T3 +:: +:: Applies a function to corresponding elements of two lists, threading +:: an accumulator argument through the computation. The lists must have +:: identical sizes. If the input function is f and the elements are i0...iN and +:: j0...jN then computes f i0 j0 (...(f iN jN s)). +:: Examples +:: > %: fold-back2 +:: (limo ~["Tails" "Head" "Tails"]) +:: (limo ~["Tails" "Head" "Head"]) +:: `(list tape)`~ +:: |=([n1=tape n2=tape state=(list tape)] [(weld n1 n2) state]) +:: == +:: ~["TailsTails" "HeadHead" "TailsHead"] +:: Source +++ fold-back2 + |* [a=(list) b=(list) c=* d=$-([* * *] *)] + (fold2 (flop a) (flop b) c d) +:: +forall: [(list T) predicate:$-(T ?)] -> ? +:: +:: Tests if all elements of the list satisfy the given predicate. +:: Examples +:: > (forall (limo ~[2 4 8]) |=(a=@ ?:(=(0 (mod a 2)) %.y %.n))) +:: %.y +:: > (forall (limo ~[2 1 8]) |=(a=@ ?:(=(0 (mod a 2)) %.y %.n))) +:: %.n +:: Source +++ forall + |* [a=(list) predicate=$-(* ?)] + |- ^- ? + ?~ a %.y + ?. (predicate i.a) %.n + $(a t.a) +:: +forall2: [(list T1) (list T2) predicate:$-([T1 T2] ?)] -> ? +:: +:: Tests if all corresponding elements of the list satisfy the given +:: predicate pairwise. Crashes on lists of unequal length +:: Examples +:: > %: forall2 +:: (limo ~[1 4 8]) +:: (limo ~[3 4 8]) +:: |=([a=@ b=@] ?:(=(0 (mod (add a b) 2)) %.y %.n)) +:: == +:: %.y +:: > %: forall2 +:: (limo ~[1 5 8]) +:: (limo ~[3 4 8]) +:: |=([a=@ b=@] ?:(=(0 (mod (add a b) 2)) %.y %.n)) +:: == +:: %.n +:: Crash +:: 'lists of unequal length' +:: Source +++ forall2 + |* [a=(list) b=(list) predicate=$-(* ?)] + ?. =((lent a) (lent b)) ~|('lists of unequal length' !!) + |- ^- ? + ?~ a %.y + ?~ b ~|('cant get here' !!) + ?. (predicate i.a i.b) %.n + $(a t.a, b t.b) +:: +from-map: (map) -> (list [* *]) +:: +:: Produces the list of all key element pairs in map. +:: Examples +:: > =map-00 (to-map (limo ~[['aa' 1] ['bb' 2] ['cc' 3] ['dd' 4]])) +:: > (from-map map-00) +:: ~[[p='bb' q=2] [p='dd' q=4] [p='cc' q=3] [p='aa' q=1]] +:: Source +++ from-map + |* a=(map) + ~(tap by a) +:: +from-set: -> (list) +:: +:: Produces the list of element in set +:: Examples +:: > (from-set `(set tap)`[[n="tlon"] l=["urbit" ~ ~] r=["uqbar" ~ ~]]) +:: Source +++ from-set + |* a=(set) + ~(tap in a) +:: +get-head: (list T) -> T +:: +:: Returns the first element of the list. Crashes on empty list. +:: Examples +:: > (get-head ~[1 2]) +:: 1 +:: Crash +:: 'empty list' +:: Source +++ get-head + |* a=(list) + ?~ a ~|('empty list' !!) + i.a +:: +get-tail: (list T) -> (list T) +:: +:: Returns the list after removing the first element. +:: Examples +:: > (get-tail ~[1 2]) +:: ~[2] +:: Crash +:: 'empty list' +:: Source +++ get-tail + |* a=(list) + ?~ a ~|('empty list' !!) + t.a +:: +group-by: [(list T1) projection:$-(T1 T2)] -> (list [T2 (list T1)]) +:: +:: Applies a key-generating function to each element of a list and yields a +:: list of unique keys. Each unique key contains a list of all elements that +:: match to this key. +:: Examples +:: > (group-by (gulf 1 5) |=(a=@ (mod a 2))) +:: ~[[p=0 q=[i=4 t=~[[2 0]]]] [p=1 q=[i=5 t=~[[3 [1 0] 0]]]]] +:: Source +++ group-by + |* [a=(list) b=$-(* *)] + =/ d=(map * (list *)) ~ + |- + ?~ a ~(tap by d) + =/ e (b i.a) + =/ f (~(get by d) e) + ?~ f $(a t.a, d (~(put by d) e ~[i.a])) + $(a t.a, d (~(put by d) e ~[i.a (need f)])) +:: +indexed: (list T) -> (list [@ T]) +:: +:: Returns a new list whose elements are the corresponding elements of the +:: input list paired with the index (from 0) of each element. +:: Examples +:: > (indexed (gulf 1 3)) +:: ~[[0 1] [1 2] [2 3]] +:: Source +++ indexed + |* a=(list) + =/ b=(list [@ _?>(?=(^ a) i.a)]) ~ + =/ i 0 + |- ^- (list [@ _?>(?=(^ a) i.a)]) + ?~ a (flop b) + $(a t.a, b [[i i.a] b], i +(i)) +:: +init: [length:@ud initializer:$-(@ud T)] -> (list T) +:: +:: Creates a list by calling the given generator on each index. +:: Crashes on length = 0. +:: Examples +:: > (init 3 |=(a=@ (add a 5))) +:: ~[6 7 8] +:: Crash +:: 'empty list' +:: Source +++ init + |* [len=@ ini=$-(@ *)] + =/ a=(list *) ~ + ?: =(0 len) ~|('empty list' !!) + |- + ?: =(0 len) a + $(len (dec len), a [(ini len) a]) +:: +insert-at: [(list T) index:@ value:T] -> (list T) +:: +:: Return a new list with a new item inserted before the given index. +:: Examples +:: > (insert-at (limo ~[2 3 4]) 1 11) +:: ~[2 11 3 4] +:: Source +++ insert-at into +:: +insertManyAt: [(list T) values=(list T) index=@] -> (list T) +:: +:: Return a new list with new items inserted before the given index. +:: Examples +:: > (insert-many-at (limo ~[1 2 5 6 7]) (limo ~[3 4]) 2) +:: ~[1 2 3 4 5 6 7] +:: Crash +:: 'out of range' +:: Source +++ insert-many-at + |* [a=(list) values=(list) i=@] + ?: =(0 (lent values)) a + =/ len-a (lent a) + ?: (gth i len-a) ~|('out of range' !!) + ?~ values a + ?: =(0 i) (weld values a) + ?: =(len-a i) (weld a values) + =/ start (scag i a) + =/ end (slag i a) + (weld (weld start values) end) +:: +is-empty: (list) -> ? +:: +:: Returns true if the list contains no elements, false otherwise. +:: Examples +:: > (is-empty `(list @)`~[2]) +:: %.n +:: > (is-empty `(list @)`~) +:: %.y +:: Source +++ is-empty + |* a=(list) + ?~ a %.y %.n +:: +item: [(list T) index:@] -> T +:: +:: Indexes into the list. The first element has index 0. +:: Examples +:: > (item `(list @)`~["aa" "bb" "cc" "dd"] 2) +:: "cc" +:: Source +++ item + |* [a=(list) i=@] + (snag i a) +:: +iter: [(list T) fun:$-(T *)] -> ~ +:: +:: Applies the given function to each element of the list, dropping the +:: results. +:: Examples +:: > (iter (limo ~["tape1" "tape2"]) |=(a=tape (lent a))) +:: ~ +:: Source +++ iter + |* [a=(list) fun=$-(* *)] + =/ b (turn a fun) + ~ +:: +iter2: [(list T1) (list T2) fun:$-(T1 T2 *)] -> ~ +:: +:: Applies the given function to two lists simultaneously, dropping the +:: results. The lists must have identical size. +:: Examples +:: > %: iter2 +:: (limo ~["tape1" "tape2"]) +:: (limo ~["tape3" "tape4"]) +:: |=([a=tape b=tape] (add (lent a) (lent b))) +:: == +:: ~ +:: Crash +:: 'lists of unequal length' +:: Source +++ iter2 + |* [a=(list) b=(list) fun=$-(* *)] + =/ b (map2 a b fun) + ~ +:: +iteri: [(list T) fun:$-([@ T] *)] -> ~ +:: +:: Applies the given function to each element of the list and the index +:: of element, dropping the results. +:: Examples +:: > (iteri (limo ~[1 2 3]) |=([a=@ b=@] (add a b))) +:: ~ +:: Source +++ iteri +|* [a=(list) fun=$-(* *)] + =/ b (mapi a fun) + ~ +:: +iteri2: [(list T1) (list T2) fun:$-(@ T1 T2 *)] -> ~ +:: +:: Applies the given function to two lists and the current index, +:: dropping the results. The lists must have identical size. +:: Examples +:: > %: iteri2 +:: (limo ~[1 2 3]) +:: (limo ~[4 5 6]) +:: |=([a=@ b=@ c=@] (add (add a b) c)) +:: == +:: ~ +:: Crash +:: 'lists of unequal length' +:: Source +++ iteri2 + |* [a=(list) b=(list) fun=$-(* *)] + =/ b (mapi2 a b fun) + ~ +:: +last-n: [(list T) count:@] -> (list T) +:: +:: Returns the last N elements of the list. +:: Examples +:: > (last-n `(list @)`[1 2 3 4 ~] 2) +:: [i=3 t=~[4]] +:: > (last-n `(list @)`[1 2 3 4 ~] 10) +:: [i=1 t=~[2 3 4]] +:: Source +++ last-n + |* [p=(list) q=@] + (flop (scag q (flop p))) +:: +length: (list T) -> @u +:: +:: Returns the length of the list. +:: Examples +:: > (length [1 2 3 4 ~]) +:: 4 +:: > (length [1 'a' 2 'b' (some 10) ~]) +:: 5 +:: Source +++ length lent +:: +map-seq: [(list T1) mapping:$-(T1 T2)] -> (list T2) +:: +:: Builds a new list whose elements are the results of applying the given +:: gate to each of the elements of the list. +:: Examples +:: > (map (limo [104 111 111 110 ~]) @t) +:: <|h o o n|> +:: > =a |=(a=@ (add a 4)) +:: > (map (limo [1 2 3 4 ~]) a) +:: ~[5 6 7 8] +:: Source +++ map-seq turn +:: +map2: [(list T1) (list T2) mapping:$-([T1 T2] T3)] -> (list T3) +:: +:: Builds a new list whose elements are the results of applying the given +:: function to the corresponding elements of the two lists pairwise. +:: Crashes if lists are of unequal length +:: Examples +:: > (map2 (limo ~[1 2 3 4]) (limo ~[5 6 7 8]) |=(a=[@ @] (add -.a +.a))) +:: ~[6 8 10 12] +:: Crash +:: 'lists of unequal length' +:: Source +++ map2 + |* [a=(list) b=(list) c=gate] + =/ d=(list) ~ + |- + ?~ a ?~ b (flop d) ~|('lists of unequal length' !!) + ?~ b ~|('lists of unequal length' !!) + $(a t.a, b t.b, d [(c i.a i.b) d]) +:: +map3: [(list T1) (list T2) (list T3) $-([T1 T2 T3] T4)] -> (list T4) +:: +:: Builds a new list whose elements are the results of applying the given +:: function to the corresponding elements of the three lists +:: simultaneously. +:: Examples +:: > %: map3 +:: (limo ~[1 2 3 4]) +:: (limo ~[5 6 7 8]) +:: (limo ~[9 10 11 12]) +:: |=(a=[@ @ @] (add (add -.a +<.a) +>.a)) +:: == +:: ~[15 18 21 24] +:: Crash +:: 'lists of unequal length' +:: Source +++ map3 + |* [a=(list) b=(list) c=(list) d=gate] + =/ e=(list) ~ + |- + ?~ a ?~ b ?~ c (flop e) + ~|('lists of unequal length' !!) + ~|('lists of unequal length' !!) + ?~ b ~|('lists of unequal length' !!) + ?~ c ~|('lists of unequal length' !!) + $(a t.a, b t.b, c t.c, e [(d i.a i.b i.c) e]) +:: +map-fold: [(list T1) state:T2 $-([T1 T2] [T3 T2])] -> [(list T3) T2] +:: +:: Combines map and fold. Builds a new list whose elements are the results of +:: applying the given function to each of the elements of the input list. The +:: function is also used to accumulate a final value. +:: Examples +:: > =input `(list [@t @])`~[['in' 1] ['out' 2] ['in' 3]] +:: > =foo |* [p=[@t @] state=@] +:: ^- [[@t @] @] +:: ?: =(-.p 'in') [['in' (mul +.p 2)] (add state +.p)] +:: [['out' (mul +.p 2)] (mul state +.p)] +:: > (map-fold input 0 foo) +:: [~[['in' 2] ['out' 4] ['in' 6]] 5] +:: Source +++ map-fold spin +:: +map-fold-back: [(list T1) state:T2 $-([T1 T2] [T3 T2])] -> [(list T3) T2] +:: +:: Combines map and foldBack. Builds a new list whose elements are the results +:: of applying the given function to each of the elements of the input list, +:: starting from the end. +:: The function is also used to accumulate a final value. +:: Examples +:: > =input `(list [@t @])`~[['in' 1] ['out' 2] ['in' 3]] +:: > =foo |* [p=[@t @] state=@] +:: ^- [[@t @] @] +:: ?: =(-.p 'in') [['in' (mul +.p 2)] (add state +.p)] +:: [['out' (mul +.p 2)] (mul state +.p)] +:: > (map-fold-back input 0 foo) +:: [~[['in' 6] ['out' 4] ['in' 2]] 7] +:: Source +++ map-fold-back + |* [a=(list) state=* c=$-([* *] [* *])] + (spin (flop a) state c) +:: +mapi: [(list T1) mapping:$-([@ T1] T2)] -> (list T2) +:: +:: Builds a new list whose elements are the results of applying the given +:: function to each of the elements of the list. The integer index passed +:: to the function indicates the index (from 0) of element being transformed. +:: Examples +:: > (mapi (limo ~[1 2 3]) |=([a=@ b=@] (add a b))) +:: ~[1 3 5] +:: Source +++ mai + |* [a=(list) b=gate] + =| i=@ud + => .(a (homo a)) + ^- (list _?>(?=(^ a) (b i i.a))) + |- + ?~ a ~ + :- i=(b i i.a) + t=$(a t.a, i +(i)) +++ mapi + |* [a=(list) fun=$-([@ *] *)] + =/ i 0 + =/ b=(list) ~ + |- + ?~ a (flop b) + $(a t.a, b [(fun i i.a) b], i +(i)) +:: +mapi2: [(list T1) (list T2) mapping:$-([@ T1 T2] T3)] -> (list T3) +:: +:: Like mapi, but mapping corresponding elements from two lists of equal length. +:: Examples +:: > %: mapi2 +:: (limo ~[1 2 3]) +:: (limo ~[4 5 6]) +:: |=([a=@ b=@ c=@] (add (add a b) c)) +:: == +:: ~[5 8 11] +:: Crash +:: 'lists of unequal length' +:: Source +++ mapi2 + |* [a=(list) b=(list) fun=$-([@ * *] *)] + =/ i 0 + =/ c=(list) ~ + |- + ?~ a ?~ b (flop c) ~|('lists of unequal length' !!) + ?~ b ~|('lists of unequal length' !!) + $(a t.a, b t.b, c [(fun i i.a i.b) c], i +(i)) +:: +maxi: (list T) -> T +:: +:: Return the greatest of all elements of the list, compared via Operators.max. +:: Examples +:: > (maxi (limo ~[10 12 11])) +:: 12 +:: > (maxi (limo ~["max" "add" "busy"])) +:: Crash +:: 'empty list' +:: Source +++ maxi + |* a=(list) + ~| 'empty list' + =/ m -.a + |- + ?~ a m + ?: (aor m i.a) $(m i.a, a t.a) + $(a t.a) +:: +maxBy: [(list T) projection:$-(* *)] -> T +:: +:: Returns the greatest of all elements of the list, compared via Operators.max +:: on the function result. +:: Examples +:: > (max-by (limo ~["aa" "mmmm" "zzz"]) |=(a=tape (lent a))) +:: "mmmm" +:: Crash +:: 'empty list' +:: Source +++ max-by + |* [a=(list) q=$-(* *)] + ~| 'empty list' + =/ m -.a + |- + ?~ a m + ?: (aor (q m) (q i.a)) $(m i.a, a t.a) + $(a t.a) +:: +mini: (list T) +:: +:: Returns the lowest of all elements of the list, compared via Operators.min. +:: Examples +:: > (mini (limo ~[11 12 10])) +:: 10 +:: > (mini (limo ~["min" "add" "busy"])) +:: "add" +:: Crash +:: 'empty list' +:: Source +++ mini + |* a=(list) + ~| 'empty list' + =/ m -.a + |- + ?~ a m + ?. (aor m i.a) $(m i.a, a t.a) + $(a t.a) +:: +minBy: (list T) projection +:: +:: Returns the lowest of all elements of the list, compared via Operators.min +:: on the function result +:: Examples +:: > (min-by (limo ~["aa" "mmmm" "zzz"]) |=(a=tape (lent a))) +:: "aa" +:: Crash +:: 'empty list' +:: Source +++ min-by + |* [a=(list) q=$-(* *)] + ~| 'empty list' + =/ m -.a + |- + ?~ a m + ?. (aor (q m) (q i.a)) $(m i.a, a t.a) + $(a t.a) +:: +pairwise: (list T) -> (list [T T]) +:: +:: Returns a list of each element in the input list and its predecessor, with +:: the exception of the first element which is only returned as the predecessor +:: of the second element. +:: Examples +:: > (pairwise (limo ~[1 2 3 4])) +:: ~[[1 2] [2 3] [3 4]] +:: Source +++ pairwise + |* a=(list) + =/ b=(list [_?>(?=(^ a) i.a) _?>(?=(^ a) i.a)]) ~ + |- + ?: (lth (lent a) 2) (flop b) + ?~ a ~|('cant get here' !!) + ?~ t.a ~|('cant get here' !!) + $(a t.a, b [[i.a i.t.a] b]) +:: +partition: [(list T) predicate:$-( T ?)] -> [(list T) (list T)] +:: +:: Splits the list into two lists, containing the elements for +:: which the given predicate returns True and False respectively. Element order +:: is preserved in both of the created lists. +:: Examples +:: > =a |=(a=@ (gth a 1)) +:: > (partition `(list @)`[0 1 2 3 ~] a) +:: [p=[i=2 t=~[3]] q=[i=0 t=~[1]]] +:: Source +++ partition skid +:: +permute: [(list T) projection:$-(@ @)] -> (list T) +:: +:: Returns a list with all elements permuted according to the permutation +:: specified by operating on the element indices. +:: Examples +:: > (permute (limo ~[1 2 3 4]) |=(i=@ (mod +(i) 4))) +:: ~[4 1 2 3] +:: Source +++ permute + |* [a=(list) q=$-(@ @)] + =/ b=(list [@ _?>(?=(^ a) i.a)]) ~ + =/ i 0 + |- + ?~ a +:(unzip (sort b aor)) + $(a t.a, b [[(q i) i.a] b], i +(i)) +:: +reduce: [(list T) reduction:$-([T T] T)] -> T +:: +:: Apply a function to each element of the list, threading an accumulator +:: argument through the computation. Apply the function to the first two +:: elements of the list. Then feed this result into the function along with the +:: third element and so on. Return the final result. If the input function is f +:: and the elements are i0...iN then computes f (... (f i0 i1) i2 ...) iN. +:: Examples +:: > %+ reduce +:: `(list tape)`~["urbit" "is" "fun"] +:: |=([a=tape b=tape] (welp (snoc a ' ') b)) +:: "urbit is fun" +:: Crash +:: 'empty list' +:: Source +++ reduce + |* [a=(list) q=$-([* *] *)] + ?~ a ~|('empty list' !!) + =/ b `_?>(?=(^ a) i.a)`i.a + =/ c t.a + |- + ?~ c b + $(b (q b i.c), c t.c) +:: +reduceBack: [(list T) reduction:$-([T T] T)] -> T +:: +:: Applies a function to each element of the list, starting from the end, +:: threading an accumulator argument through the computation. If the input +:: function is f and the elements are i0...iN then computes +:: f i0 (...(f iN-1 iN)). +:: Examples +:: > %+ reduce-back +:: `(list tape)`~["urbit" "is" "fun"] +:: |=([a=tape b=tape] (welp (snoc a ' ') b)) +:: "fun is urbit" +:: Crash +:: 'empty list' +:: Source +++ reduce-back + |* [a=(list) q=$-([* *] *)] + (reduce (flop a) q) +:: +remove-at: [(list T) index:@] -> (list T) +:: +:: Return a new list with the item at a given index removed. +:: Examples +:: > (remove-at "good day, urbit!" 8) +:: "good day urbit!" +:: > (remove-at `(list @)`[1 2 3 4 ~] 2) +:: ~[1 2 4] +:: Crash +:: 'out of range' +:: Source +++ remove-at + |* [a=(list) i=@] + ?: (gte i (lent a)) ~|('out of range' !!) + (oust [i 1] a) +:: +remove-many-at: [(list T) index=@ count=@] -> (list T) +:: +:: Return a new list with the number of items starting at a given index removed +:: Examples +:: > (remove-many-at "good day, urbit!" [4 5]) +:: "good urbit!" +:: > (remove-many-at `(list @)`[1 2 3 4 ~] [2 2]) +:: ~[1 2] +:: Crash +:: 'out of range' +:: Source +++ remove-many-at + |* [a=(list) i=@ c=@] + ?: (gth (add i c) (lent a)) ~|('out of range' !!) + (oust [i c] a) +:: +replicate: [count=@ initial=T] -> (list T) +:: +:: Creates a list by replicating the given initial value. +:: Examples +:: > (replicate 20 %a) +:: ~[%a %a %a %a %a %a %a %a %a %a %a %a %a %a %a %a %a %a %a %a] +:: > (replicate 5 ~s1) +:: ~[~s1 ~s1 ~s1 ~s1 ~s1] +:: > `@dr`(roll (replicate 5 ~s1) add) +:: ~s5 +:: Source +++ replicate reap +:: +reverse: (list T) -> (list T) +:: +:: Returns a new list with the elements in reverse order. +:: Examples +:: > =a [1 2 3 ~] +:: > (flop a) +:: ~[3 2 1] +:: > (flop (flop a)) +:: ~[1 2 3] +:: Source +++ reverse flop +:: +scanx: [(list T1) state:T2 folder:$-([T1 T2] T2)] -> (list T2) +:: +:: Applies a function to each element of the list and an accumulator, threading +:: the accumulator argument through the computation. Returns the list of +:: intermediate results and the final result. +:: Examples +:: > %: scanx +:: `(list tape)`~["urbit" "is" "fun"] +:: "" +:: |=([a=tape b=tape] (welp (snoc b ' ') a)) +:: == +:: ~["" " urbit" "urbit is" " urbit is fun"] +:: Source +++ scanx + |* [a=(list) state=* fun=$-([* *] *)] + =/ b=(list _state) ~ + |- ^- (list _?>(?=(^ a) i.a)) + ?~ a (flop [state b]) + $(a t.a, b [state b], state (fun i.a state)) +:: +scan-back: [(list T) state:T2 folder:$-(T1 T2)] -> (list T2) +:: +:: Like fold-back, but returns both the intermediary and final results +:: Examples +:: Source +++ scan-back + |* [a=(list) state=* fun=$-([* *] *)] + =/ c=(list _?>(?=(^ a) i.a)) (flop a) + =/ b=(list _state) ~ + |- ^- (list _?>(?=(^ a) i.a)) + ?~ c (flop [state b]) + $(c t.c, b [state b], state (fun i.c state)) +:: +singleton: value: T -> (list T) +:: +:: Returns a list that contains one item only. +:: Examples +:: > (singleton "tape") +:: ~["tape"] +:: Source +++ singleton + |* a=* + (limo ~[a]) +:: +skip-n: [(list T) count:@] -> (list T) +:: +:: Returns the list after removing the first N elements. +:: Examples +:: > (skip-n `(list @)`[1 2 3 4 ~] 2) +:: ~[3 4] +:: Crash +:: 'out of range' +:: Source +++ skip-n + |* [p=(list) q=@] + ?~ p ?~ q p ~|('out of range' !!) + ?~ q p + $(p t.p, q (dec q)) +:: +skip-while: [(list T) predicate:$-(T ?)] -> (list T) +:: +:: Bypasses elements in a list while the given predicate returns True, and then +:: returns the remaining elements of the list. +:: Examples +:: > %: skip-while +:: (limo ~["a" "bbb" "cc" "d"]) +:: |=(a=tape (lth (lent a) 3)) +:: == +:: ~["bbb" "cc" "d"] +:: Source +++ skip-while + |* [a=(list) b=$-(* ?)] + =/ c=(list _?>(?=(^ a) i.a)) ~ + |- ^+ a + ?~ a (flop c) + ?~ c ?: (b i.a) $(a t.a) $(a t.a, c [i.a c]) + $(a t.a, c [i.a c]) +:: +sort-by: [(list T) projection:$-(T *)] -> (list T) +:: +:: Sorts the given list using keys given by the given projection. Keys are +:: compared using Operators.compare. +:: Examples +:: > (sort-by (limo ~["bb" "a" "dddd" "ccc"]) |=(a=tape (lent a))) +:: ~["a" "bb" "ccc" "dddd"] +:: Source +++ sort-by + |* [a=(list) proj=$-(* *)] + =/ b (turn a proj) + =/ c (zip b a) + +:(unzip (sort c aor)) +:: +sort-by-descending: [(list T) projection:$-(T *)] -> (list T) +:: +:: Sorts the given list in descending order using keys given by the given +:: projection. Keys are compared using Operators.compare. +:: Examples +:: > %: sort-by-descending +:: (limo ~["bb" "a" "dddd" "ccc"]) |=(a=tape (lent a)) +:: == +:: ~["dddd" "ccc" "bb" "a"] +:: Source +++ sort-by-descending + |* [a=(list) proj=$-(* *)] + =/ b (turn a proj) + =/ c (zip b a) + +:(unzip (sort c |=([a=* b=*] (aor b a)))) +:: +sort-descending: (list T) -> (list T) +:: +:: Sorts the given list in descending order using Operators.compare. +:: Examples +:: > (sort-descending (limo ~[4 2 1 3])) +:: ~[4 3 2 1] +:: Source +++ sort-descending + |* a=(list) + (sort a |=([a=* b=*] (aor b a))) +:: +sort-qik: (list T) -> (list T) +:: +:: Sorts the given list in ascending order using Operators.compare. +:: Examples +:: > (sort-qik (limo ~[4 2 1 3])) +:: ~[1 2 3 4] +:: Source +++ sort-qik + |* a=(list) + (sort a aor) +:: +split-at: [(list T) index:@] -> [(list T) (list T)] +:: +:: Splits a list into two lists, at the given index. +:: Examples +:: > (split-at (limo ~[1 2 3 4 5]) 2) +:: [~[1 2] ~[3 4 5]] +:: Source +++ split-at + |* [p=(list) i=@] + [(scag i p) (slag i p)] +:: +split-into: [(list T) count:@] -> (list (list T)) +:: +:: Splits the input list into at most count chunks. +:: Examples +:: > (split-into (gulf 1 10) 4) +:: Crash +:: 'count is 0' +:: Source +++ split-into + |* [a=(list) i=@] + ?~ i ~|('count is 0' !!) + =/ b=(list (list _?>(?=(^ a) i.a))) ~ + |- + ?: =(0 (lent a)) (flop b) + =/ q (div (lent a) i) + =/ r (mod (lent a) i) + =/ l ?: =(0 r) q +(q) + =/ c=(list _?>(?=(^ a) i.a)) ~ + |- + ?~ l ^$(b [(flop c) b], i (dec i)) + ?~ a ?~ c (flop b) (flop [(flop c) b]) + $(c [i.a c], l (dec l), a t.a) +:: +sum: (list @) -> @ +:: +:: Returns the sum of the elements in the list. +:: Examples +:: > (sum (limo ~[1 2 3])) +:: 6 +:: Source +++ sum + |* a=(list @) + =/ b=@ 0 + |- + ?~ a b + $(a t.a, b (add b i.a)) +:: +sum-by: [(list T) projection:$-(T @)] -> @ +:: +:: Returns the sum of the results generated by applying the function to each +:: element of the list. +:: Examples +:: > (sum-by (limo ~["a" "bb" "ccc"]) |=(a=tape (lent a))) +:: 6 +:: Source +++ sum-by + |* [a=(list) proj=$-(* @)] + =/ b=@ 0 + |- + ?~ a b + $(a t.a, b (add b (proj i.a))) +:: +tail-end: (list T) -> T +:: +:: Returns the last element of the list. +:: Crash when the input does not have any elements. +:: Examples +:: > (last ~[1 2 3]) +:: 3 +:: Crash +:: 'empty list' +:: Source +++ tail-end + |* a=(list) + ?~ a ~|('empty list' !!) + (rear a) +:: +take-while: [(list T) predicate:$-(T ?)] -> (list T) +:: +:: Returns a list that contains all elements of the original list while the +:: given predicate returns True, and then returns no further elements. +:: Examples +:: > %: take-while +:: (limo ~["a" "bb" "ccc" "d"]) +:: |=(a=tape (lth (lent a) 3)) +:: == +:: ~["a" "bb"] +:: Source +++ take-while + |* [a=(list) b=$-(* ?)] + =/ c=(list _?>(?=(^ a) i.a)) ~ + |- ^+ a + ?~ a (flop c) + ?: (b i.a) $(a t.a, c [i.a c]) + (flop c) +:: +to-map: (list [* *]) -> +:: +:: Produces a map from a list. +:: Examples +:: > (to-map (limo ~[['aa' 1] ['bb' 2] ['cc' 3] ['dd' 4]])) +:: [n=[p='dd' q=4] l=[n=[p='cc' q=3] l=[n=[p='aa' q=1] l=~ r=~] r=~] +:: r=[n=[p='bb' q=2] l=~ r=~]] +:: Source +++ to-map + |* a=(list) + (malt a) +:: +to-set: (list) -> +:: +:: Produces a set from a list. +:: Examples +:: > (to-map (limo ~[['aa' 1] ['bb' 2] ['cc' 3] ['dd' 4]])) +:: [n=['dd' 4] l=[n=['cc' 3] l=[n=['aa' 1] ~ ~] ~] r=[n=['bb' 2] ~ ~]] +:: Source +++ to-set + |* a=(list) + (silt a) +:: +transpose: (list (list T)) -> ?([~ ~] (list (list T))) +:: +:: Returns the transpose of the given sequence of lists. +:: Returns [~ ~] when all lists of list are ~. +:: Examples +:: > %- transpose +:: %: limo +:: (limo ~["a" "b" "c"]) +:: (limo ~["aa" "bb" "cc"]) +:: (limo ~["aaa" "bbb" "ccc"]) +:: ~ +:: == +:: ~[~["a" "aa" "aaa"] ~["b" "bb" "bbb"] ~["c" "cc" "ccc"]] +:: Crash +:: 'lists of unequal length' +:: Source +++ transpose + |* a=(list (list)) + =/ aa a + =/ equal=? %.y + ~| 'lists of unequal length' + |- ^- (list (list _?>(?=(^ ^ a) -.-.a))) + ?: =(%.n equal) !! + ?~ aa (transpose-jgd a) + ?~ t.aa (transpose-jgd a) + ?: =((lent i.aa) (lent i.t.aa)) $(aa t.aa) $(equal %.n) +:: +transpose-jgd: (list (list T)) -> ?([~ ~] (list (list T))) +:: +:: Returns the jagged transpose of the given sequence of lists. +:: Returns [~ ~] when all lists of list are ~. +:: Examples +:: > %- transpose-jgd +:: %: limo +:: (limo ~["a" "b" "c"]) +:: (limo ~["aa" "cc"]) +:: (limo ~["aaa" "bbb" "ccc"]) +:: ~ +:: == +:: ~[~["a" "aa" "aaa"] ~["b" "cc" "bbb"] ~["c" "ccc"]] +:: Source +++ transpose-jgd + |* a=(list (list)) + =/ aa=(list (list _?>(?=(^ ^ a) -.-.a))) a + =/ b=(list (list _?>(?=(^ ^ a) -.-.a))) ~ + =/ bb=(list _?>(?=(^ ^ a) -.-.a)) ~ + |- ^- (list (list _?>(?=(^ ^ a) -.-.a))) + ?~ a (flop b) + =/ c=(list (list _?>(?=(^ ^ a) -.-.a))) ~ + |- + ?~ aa + %= ^$ + a (flop c) + aa (flop c) + b [(flop bb) b] + bb ~ + == + ?~ -.aa $(aa t.aa) + ?~ ->.aa $(aa t.aa, bb [-<.aa bb]) + $(aa t.aa, bb [-<.aa bb], c [->.aa c]) +:: +try-exactly-one: (list T) -> (unit T) +:: +:: Returns the only element of the list or None if it is empty or contains more +:: than one element. +:: Examples +:: > (try-exactly-one (limo ~["tape"])) +:: [~ i=[i=t' t="ape"]] +:: Source +++ try-exactly-one + |* a=(list) + ?: =(1 (lent a)) `-.a + ~ +:: +try-find: [(list T) predicate:$-(T ?)] -> (unit T) +:: +:: Returns the first element for which the given function returns True. +:: Return None if no such element exists. +:: Examples +:: > (try-find (gulf [1 30]) |=(a=@ud ?&(=(0 (mod a 3)) =(0 (mod a 5))))) +:: `15 +:: Source +++ try-find + |* [a=(list) b=$-(* ?)] + |- ^- (unit _?>(?=(^ a) i.a)) + ?~ a ~ + ?: (b i.a) `i.a $(a t.a) +:: +try-find-back: [(list T) predicate:$-(T ?)] -> (unit T) +:: +:: Returns the last element for which the given function returns True. +:: Return None if no such element exists. +:: Examples +:: > %: try-find-back +:: (gulf [1 30]) +:: |=(a=@ud ?&(=(0 (mod a 3)) =(0 (mod a 5)))) +:: == +:: `30 +:: Source +++ try-find-back + |* [a=(list) b=$-(* ?)] + ?~ a ~ + (try-find (flop a) b) +:: +try-find-by-unit: [(list T) chooser:$-(T (unit T))] -> (unit T) +:: +:: Applies the given function to successive elements, returning Some(x) for the +:: first result where function returns Some(x). +:: If no such element exists then return None. +:: Examples +:: > (search-by-unit (limo ~[1 2 3 4]) |=(a=@ ?:(=((mod a 2) 0) `a ~))) +:: `2 +:: Crash +:: 'not found' +:: Source +++ try-find-by-unit + |* [hstk=(list) nedl=$-(* (unit *))] + |- ^- (unit _?>(?=(^ hstk) i.hstk)) + ?~ hstk ~ + =/ x (nedl i.hstk) + ?~ x $(hstk t.hstk) x +:: +try-find-index: [(list T) predicate:$-(T ?)] -> (unit @) +:: +:: Returns the index of the first element in the list that satisfies the given +:: predicate. Return None if no such element exists. +:: Examples +:: > %: try-find-index +:: (gulf [1 30]) +:: |=(a=@ud ?&(=(0 (mod a 3)) =(0 (mod a 5)))) +:: == +:: `14 +:: Source +++ try-find-index + |* [a=(list) b=$-(* ?)] + =/ i 0 + |- ^- (unit @) + ?~ a ~ + ?: (b i.a) `i $(a t.a, i +(i)) +:: +try-find-index-back: [(list T) predicate:$-(T ?)] -> (unit @) +:: +:: Returns the index of the last element in the list that satisfies the given +:: predicate. Return None if no such element exists. +:: Examples +:: > %: try-find-index-back +:: (gulf [1 30]) +:: |=(a=@ud ?&(=(0 (mod a 3)) =(0 (mod a 5)))) +:: == +:: `29 +:: Source +++ try-find-index-back + |* [a=(list) c=$-(* ?)] + ?~ a ~ + =/ b (flop a) + =/ i (dec (lent a)) + |- ^- (unit @ud) + ?~ b ~ + ?: (c i.b) `i + ?: =(0 i) ~ + $(b t.b, i (dec i)) +:: +try-head: (list T) -> (unit T) +:: +:: Returns the first element of the list, or None if the list is empty. +:: Examples +:: > (try-head ~[1 2]) +:: `1 +:: Source +++ try-head + |* a=(list) + ?~ a ~ + `i.a +:: +try-item: [(list T) index:@] -> (unit T) +:: +:: Tries to find the nth element in the list. Returns None if index is negative +:: or the list does not contain enough elements. +:: Examples +:: > (try-item `(list @)`~["aa" "bb" "cc" "dd"] 2) +:: [~ "cc"] +:: > (try-item `(list tape)`~["aa" "bb"] 2) +:: ~ +:: Source +++ try-item + |* [a=(list) i=@] + ?: (gte i (lent a)) ~ + `(snag i a) +:: +try-remove-at: [(list T) index:@] -> (unit (list T)) +:: +:: Attempt a new list with the item at a given index removed returning +:: Some((list T)) upon success. +:: Examples +:: > (try-remove-at "good day, urbit!" 8) +:: [~ "good day urbit!"] +:: > (try-remove-at `(list @)`[1 2 3 4 ~] 2) +:: [~ ~[1 2 4]] +:: Source +++ try-remove-at + |* [a=(list) i=@] + ?: (gte i (lent a)) ~ + `(oust [i 1] a) +:: +try-remove-many-at: [(list T) index=@ count=@] -> (list T) +:: +:: Return a new list with the number of items starting at a given index removed +:: returning Some((list T)) upon success. +:: Examples +:: > (try-remove-many-at "good day, urbit!" [4 5]) +:: [~ "good urbit!"] +:: > (try-remove-many-at `(list @)`[1 2 3 4 ~] [2 2]) +:: [~ ~[1 2]] +:: Source +++ try-remove-many-at + |* [a=(list) i=@ c=@] + ?: (gth (add i c) (lent a)) ~ + `(oust [i c] a) +:: +try-tail: (list T) -> (unit (list T)) +:: +:: Returns the elements of the list after the first. +:: Examples +:: > (try-tail ~[1 2]) +:: `~[2] +:: Source +++ try-tail + |* a=(list) + ?~ a ~ + `t.a +:: +try-tail-end: (list T) -> (unit T) +:: +:: Returns the last element of the list. Return None if no such element exists. +:: Examples +:: > (try-tail-end ~[1 2 3]) +:: `3 +:: Source +++ try-tail-end + |* a=(list) + ?~ a ~ + `(rear a) +:: +try-update-at: [(list T) index:@ value:T] -> (list T) +:: +:: Return a new list with the item at a given index set to the new value. +:: Examples +:: > (try-update-at (limo ~[2 3 4]) 1 11) +:: [~ ~[2 11 4]] +:: > (try-update-at (limo ~[2 3 4]) 3 11) +:: ~ +:: Crash +:: 'not found' +:: Source +++ try-update-at + |* [a=(list) b=@ c=*] + ?: (gte b (lent a)) ~ + `(snap a b c) +:: +unfold: [state:T1 generator:$-(T1 -> (unit [T1 T2]))] -> (list T2) +:: +:: Returns a list that contains the elements generated by the given computation +:: The generator is repeatedly called to build the list until it returns None. +:: The given initial state argument is passed to the element generator. +:: Examples +:: > (unfold 1 |=(a=@ ?:((gth a 100) ~ `[(mul a 2) a]))) +:: ~[1 2 4 8 16 32 64] +:: Source +++ unfold + |* [state=* gen=$-(* (unit [* *]))] + =/ res=(list) ~ + |- + =/ x (gen state) + ?~ x (flop res) + =/ y (need x) + $(state -.y, res [+.y res]) +:: +unzip: (list [T1 T2]) - [(list T1) (list T2)] +:: +:: Splits a list of pairs into two lists. +:: Examples +:: > (unzip (limo ~[[1 "aa"] [2 "bb"]])) +:: [~[1 2] ~["aa" "bb"]] +:: Source +++ unzip + |* a=(list [* *]) + =/ b=(list *) ~ + =/ c=(list *) ~ + |- + ?~ a [(flop b) (flop c)] + $(a t.a, b [-.i.a b], c [+.i.a c]) +:: +unzip3: (list [T1 T2 T3]) - [(list T1) (list T2) (list T3)] +:: +:: Splits a list of triples into three lists. +:: Examples +:: > (unzip3 (limo ~[[1 "aa" 'a'] [2 "bb" 'b']])) +:: [~[1 2] ~["aa" "bb"] ~['a' 'b']] +:: Source +++ unzip3 + |* a=(list [* *]) + =/ b=(list *) ~ + =/ c=(list *) ~ + =/ d=(list *) ~ + |- + ?~ a [(flop b) (flop c) (flop d)] + $(a t.a, b [-.i.a b], c [+<.i.a c], d [+>.i.a d]) +:: +update-at: [(list T) index:@ value:T] -> (list T) +:: +:: Return a new list with the item at a given index set to the new value. +:: Examples +:: > (update-at (limo ~[2 3 4]) 1 11) +:: ~[2 11 4] +:: Crash +:: 'not found' +:: Source +++ update-at + |* [a=(list) b=@ c=*] + ?: (gte b (lent a)) ~|('not found' !!) + (snap a b c) +:: +windowed: [(list T) window-size:@] -> (list (list T)) +:: +:: Returns a list of sliding windows containing elements drawn from the input +:: list. Each window is returned as a fresh list. +:: Examples +:: > (windowed (limo ~[1 2 3 4 5]) 3) +:: ~[~[1 2 3] ~[2 3 4] ~[3 4 5]] +:: Crash +:: 'empty list' +:: 'window length is 0' +:: 'list shorter than window' +:: Source +++ windowed + |* [p=(list *) q=@] + ?~ q ~|('window length is 0' !!) + =/ b=(list (list _?>(?=(^ p) i.p))) ~ + =/ sub-tree=(list _?>(?=(^ p) i.p)) ~ + =/ pp=(list _?>(?=(^ p) i.p)) p + |- ^- (list (list _?>(?=(^ p) i.p))) + ?~ p ~|('empty list' !!) + ?~ pp ?: (lth (lent sub-tree) q) + ?~ b ~|('list shorter than window' !!) (flop b) + $(pp t.p, b [(flop sub-tree) b], sub-tree ~) + ?: =((lent sub-tree) q) + $(p t.p, pp t.p, b [(flop sub-tree) b], sub-tree ~) + $(pp t.pp, sub-tree [i.pp sub-tree]) +:: +zip: [(list T1) (list T2)] -> (list [T1 T2]) +:: +:: Combines the two lists into a list of pairs. The two lists must have equal +:: lengths. +:: Examples +:: > (zip `(list @)`~[1 2] `(list @)`~["aa" "bb"]) +:: ~[[1 "aa"] [2 "bb"]] +:: Crash +:: 'lists of unequal length' +:: Source +++ zip + |* [a=(list) b=(list)] + =/ c=(list [_?>(?=(^ a) i.a) _?>(?=(^ b) i.b)]) ~ + |- ^- (list [_?>(?=(^ a) i.a) _?>(?=(^ b) i.b)]) + ?~ a ?~ b (flop c) ~|('lists of unequal length' !!) + ?~ b ~|('lists of unequal length' !!) + $(a t.a, b t.b, c [[i.a i.b] c]) +:: +zip3: [(list T1) (list T2) (list T3)] -> (list [T1 T2 T3]) +:: +:: Combines the three lists into a list of triples. The lists must have equal +:: lengths. +:: Examples +:: > %: zip3 +:: `(list @)`~[1 2] +:: `(list tape)`~["aa" "bb"] +:: `(list @t)`~['a' 'b'] +:: == +:: ~[[1 "aa" 'a'] [2 "bb" 'b']] +:: Crash +:: 'lists of unequal length' +:: Source +++ zip3 + |* [a=(list) b=(list) c=(list)] + =/ d=(list [_?>(?=(^ a) i.a) _?>(?=(^ b) i.b) _?>(?=(^ c) i.c)]) ~ + |- ^- (list [_?>(?=(^ a) i.a) _?>(?=(^ b) i.b) _?>(?=(^ c) i.c)]) + ?~ a ?~ b ?~ c (flop d) + ~|('lists of unequal length' !!) + ~|('lists of unequal length' !!) + ?~ b ~|('lists of unequal length' !!) + ?~ c ~|('lists of unequal length' !!) + $(a t.a, b t.b, c t.c, d [[i.a i.b i.c] d]) +--
\ No newline at end of file |