on 4bec310 help sign in
elk/libraries/List.elm
278 lines 7.4 kB history raw
1module List where
3{-| A library for manipulating lists of values. Every value in a
4list must have the same type.
6# Basics
7@docs (::), (++), isEmpty, length, reverse, map
9# Sub-lists
10@docs head, tail, last, filter, take, drop
12# Putting Lists Together
13@docs concat, concatMap, join, intersperse, zip, zipWith, repeat
15# Taking Lists Apart
16@docs partition, unzip
18# Folds
19@docs foldr, foldl, foldr1, foldl1, scanl, scanl1
21# Special Folds
22@docs sum, product, maximum, minimum, all, any, and, or
24# Sorting
25@docs sort, sortBy, sortWith
26-}
28import Basics (..)
29import Native.List
31{-| Add an element to the front of a list `(1 :: [2,3] == [1,2,3])` -}
32(::) : a -> [a] -> [a]
33(::) = Native.List.cons
35{-| Puts two appendable things together:
37 [1,1] ++ [2,3] == [1,1,2,3]
38 "abc" ++ "123" == "abc123"
39-}
40(++) : appendable -> appendable -> appendable
41(++) = Native.List.append
43infixr 5 ::
44infixr 5 ++
46{-| Extract the first element of a list. List must be non-empty.
47`(head [1,2,3] == 1)`
48-}
49head : [a] -> a
50head = Native.List.head
52{-| Extract the elements after the head of the list. List must be non-empty.
53`(tail [1,2,3] == [2,3])`
54-}
55tail : [a] -> [a]
56tail = Native.List.tail
58{-| Extract the last element of a list. List must be non-empty.
59`(last [1,2,3] == 3)`
60-}
61last : [a] -> a
62last = Native.List.last
64{-| Check if a list is empty `(isEmpty [] == True)` -}
65isEmpty : [a] -> Bool
66isEmpty xs =
67 case xs of
68 [] -> True
69 _ -> False
71{-| Apply a function to every element of a list: `(map sqrt [1,4,9] == [1,2,3])` -}
72map : (a -> b) -> [a] -> [b]
73map = Native.List.map
75{-| Reduce a list from the left: `(foldl (::) [] [1,2,3] == [3,2,1])` -}
76foldl : (a -> b -> b) -> b -> [a] -> b
77foldl = Native.List.foldl
79{-| Reduce a list from the right: `(foldr (+) 0 [1,2,3] == 6)` -}
80foldr : (a -> b -> b) -> b -> [a] -> b
81foldr = Native.List.foldr
83{-| Reduce a list from the left without a base case. List must be non-empty. -}
84foldl1 : (a -> a -> a) -> [a] -> a
85foldl1 = Native.List.foldl1
87{-| Reduce a list from the right without a base case. List must be non-empty. -}
88foldr1 : (a -> a -> a) -> [a] -> a
89foldr1 = Native.List.foldr1
91{-| Reduce a list from the left, building up all of the intermediate results into a list.
93 scanl (+) 0 [1,2,3,4] == [0,1,3,6,10]
94-}
95scanl : (a -> b -> b) -> b -> [a] -> [b]
96scanl = Native.List.scanl
98{-| Same as scanl but it doesn't require a base case. List must be non-empty.
100 scanl1 (+) [1,2,3,4] == [1,3,6,10]
101-}
102scanl1 : (a -> a -> a) -> [a] -> [a]
103scanl1 = Native.List.scanl1
105{-| Keep only elements that satisfy the predicate:
106`(filter isEven [1..6] == [2,4,6])`
107-}
108filter : (a -> Bool) -> [a] -> [a]
109filter = Native.List.filter
111{-| Determine the length of a list: `(length [1,2,3] == 3)` -}
112length : [a] -> Int
113length = Native.List.length
115{-| Reverse a list. `(reverse [1..4] == [4,3,2,1])` -}
116reverse : [a] -> [a]
117reverse = Native.List.reverse
119{-| Check to see if all elements satisfy the predicate. -}
120all : (a -> Bool) -> [a] -> Bool
121all = Native.List.all
123{-| Check to see if any elements satisfy the predicate. -}
124any : (a -> Bool) -> [a] -> Bool
125any = Native.List.any
127{-| Check to see if all elements are True. -}
128and : [Bool] -> Bool
129and = foldl (&&) True
131{-| Check to see if any elements are True. -}
132or : [Bool] -> Bool
133or = foldl (||) False
135{-| Concatenate a list of appendable things:
137 concat [[1,2],[3],[4,5]] == [1,2,3,4,5]
138 concat ["tree","house"] == "treehouse"
139-}
140concat : [appendable] -> appendable
141concat = Native.List.concat
143{-| Map a given function onto a list and flatten the resulting lists.
145 concatMap f xs == concat (map f xs)
146-}
147concatMap : (a -> appendable) -> [a] -> appendable
148concatMap f list = concat (map f list)
150{-| Get the sum of the list elements. `(sum [1..4] == 10)` -}
151sum : [number] -> number
152sum = foldl (+) 0
154{-| Get the product of the list elements. `(product [1..4] == 24)` -}
155product : [number] -> number
156product = foldl (*) 1
158{-| Find the maximum element in a non-empty list: `maximum [1,4,2] == 4` -}
159maximum : [comparable] -> comparable
160maximum = foldl1 max
162{-| Find the minimum element in a non-empty list: `minimum [3,2,1] == 1` -}
163minimum : [comparable] -> comparable
164minimum = foldl1 min
166{-| Partition a list based on a predicate. The first list contains all values
167that satisfy the predicate, and the second list contains all the value that do
168not.
170 partition (\x -> x < 3) [0..5] == ([0,1,2], [3,4,5])
171 partition isEven [0..5] == ([0,2,4], [1,3,5])
172-}
173partition : (a -> Bool) -> [a] -> ([a],[a])
174partition pred =
175 let step x (ts, fs) = if pred x
176 then (x::ts, fs)
177 else (ts, x::fs)
178 in foldr step ([],[])
180{-| Combine two lists, combining them into tuples pairwise.
181If one list is longer, the extra elements are dropped.
183 zip [1,2,3] [6,7] == [(1,6),(2,7)]
184 zip == zipWith (,)
185-}
186zip : [a] -> [b] -> [(a,b)]
187zip = Native.List.zip
189{-| Combine two lists, combining them with the given function.
190If one list is longer, the extra elements are dropped.
192 zipWith (+) [1,2,3] [1,2,3,4] == [2,4,6]
193-}
194zipWith : (a -> b -> c) -> [a] -> [b] -> [c]
195zipWith = Native.List.zipWith
197{-| Decompose a list of tuples.
199 unzip [(0, True), (17, False), (1337, True)] == ([0,17,1337], [True,False,True])
200-}
201unzip : [(a,b)] -> ([a],[b])
202unzip =
203 let step (x,y) (xs, ys) = (x::xs, y::ys)
204 in foldr step ([], [])
206{-| Places the given value between all of the lists in the second
207argument and concatenates the result.
209 join "a" ["H","w","ii","n"] == "Hawaiian"
210-}
211join : appendable -> [appendable] -> appendable
212join = Native.List.join
214{-| Places the given value between all members of the given list.
216 intersperse "on" ["turtles","turtles","turtles"] == ["turtles","on","turtles","on","turtles"]
217-}
218intersperse : a -> [a] -> [a]
219intersperse sep xs =
220 case xs of
221 [] -> []
222 hd::tl ->
223 let step x rest = sep :: x :: rest
224 spersed = foldr step [] tl
225 in hd :: spersed
227{-| Take the first n members of a list: `(take 2 [1,2,3,4] == [1,2])` -}
228take : Int -> [a] -> [a]
229take = Native.List.take
231{-| Drop the first n members of a list: `(drop 2 [1,2,3,4] == [3,4])` -}
232drop : Int -> [a] -> [a]
233drop = Native.List.drop
235{-| Creates a list with *n* copies of a value:
236`(repeat 3 (0,0) == [(0,0),(0,0),(0,0)]`
237-}
238repeat : Int -> a -> [a]
239repeat = Native.List.repeat
241{-| Sort values from lowest to highest: `sort [3,1,5] == [1,3,5]`
242-}
243sort : [comparable] -> [comparable]
244sort = Native.List.sort
246{-| Sort values by a derived property.
248```haskell
249alice = { name="Alice", height=1.62 }
250bob = { name="Bob" , height=1.85 }
251chuck = { name="Chuck", height=1.76 }
253sortBy .name [chuck,alice,bob] == [alice,bob,chuck]
254sortBy .height [chuck,alice,bob] == [alice,chuck,bob]
256sortBy String.length ["mouse","cat"] == ["cat","mouse"]
257```
258-}
259sortBy : (a -> comparable) -> [a] -> [a]
260sortBy = Native.List.sortBy
262{-| Sort values with a custom comparison function.
264```haskell
265sortWith flippedComparison [1..5] == [5,4,3,2,1]
267flippedComparison a b =
268 case compare a b of
269 LT -> GT
270 EQ -> EQ
271 GT -> LT
272```
274This is also the most general sort function, allowing you
275to define any other: `sort == sortWith compare`
276-}
277sortWith : (a -> a -> Order) -> [a] -> [a]
278sortWith = Native.List.sortWith