on 577fc17 help sign in
elk/libraries/List.elm
305 lines 8.3 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
27# Additional Zips
28@docs zip3, zip4, zip5, zipWith3, zipWith4, zipWith5
30If you can think of a legitimate use of `zipN` or `zipWithN` where `N` is 6 or
31more, please let us know on [the
32list](https://groups.google.com/forum/#!forum/elm-discuss). The current
33sentiment is that it is already quite error prone once you get to 4 and
34possibly should be approached another way.
35-}
37import Basics (..)
38import Native.List
40{-| Add an element to the front of a list `(1 :: [2,3] == [1,2,3])` -}
41(::) : a -> [a] -> [a]
42(::) = Native.List.cons
44{-| Puts two appendable things together:
46 [1,1] ++ [2,3] == [1,1,2,3]
47 "abc" ++ "123" == "abc123"
48-}
49(++) : appendable -> appendable -> appendable
50(++) = Native.List.append
52infixr 5 ::
53infixr 5 ++
55{-| Extract the first element of a list. List must be non-empty.
56`(head [1,2,3] == 1)`
57-}
58head : [a] -> a
59head = Native.List.head
61{-| Extract the elements after the head of the list. List must be non-empty.
62`(tail [1,2,3] == [2,3])`
63-}
64tail : [a] -> [a]
65tail = Native.List.tail
67{-| Extract the last element of a list. List must be non-empty.
68`(last [1,2,3] == 3)`
69-}
70last : [a] -> a
71last = Native.List.last
73{-| Check if a list is empty `(isEmpty [] == True)` -}
74isEmpty : [a] -> Bool
75isEmpty xs =
76 case xs of
77 [] -> True
78 _ -> False
80{-| Apply a function to every element of a list: `(map sqrt [1,4,9] == [1,2,3])` -}
81map : (a -> b) -> [a] -> [b]
82map = Native.List.map
84{-| Reduce a list from the left: `(foldl (::) [] [1,2,3] == [3,2,1])` -}
85foldl : (a -> b -> b) -> b -> [a] -> b
86foldl = Native.List.foldl
88{-| Reduce a list from the right: `(foldr (+) 0 [1,2,3] == 6)` -}
89foldr : (a -> b -> b) -> b -> [a] -> b
90foldr = Native.List.foldr
92{-| Reduce a list from the left without a base case. List must be non-empty. -}
93foldl1 : (a -> a -> a) -> [a] -> a
94foldl1 = Native.List.foldl1
96{-| Reduce a list from the right without a base case. List must be non-empty. -}
97foldr1 : (a -> a -> a) -> [a] -> a
98foldr1 = Native.List.foldr1
100{-| Reduce a list from the left, building up all of the intermediate results into a list.
102 scanl (+) 0 [1,2,3,4] == [0,1,3,6,10]
103-}
104scanl : (a -> b -> b) -> b -> [a] -> [b]
105scanl = Native.List.scanl
107{-| Same as scanl but it doesn't require a base case. List must be non-empty.
109 scanl1 (+) [1,2,3,4] == [1,3,6,10]
110-}
111scanl1 : (a -> a -> a) -> [a] -> [a]
112scanl1 = Native.List.scanl1
114{-| Keep only elements that satisfy the predicate:
115`(filter isEven [1..6] == [2,4,6])`
116-}
117filter : (a -> Bool) -> [a] -> [a]
118filter = Native.List.filter
120{-| Determine the length of a list: `(length [1,2,3] == 3)` -}
121length : [a] -> Int
122length = Native.List.length
124{-| Reverse a list. `(reverse [1..4] == [4,3,2,1])` -}
125reverse : [a] -> [a]
126reverse = Native.List.reverse
128{-| Check to see if all elements satisfy the predicate. -}
129all : (a -> Bool) -> [a] -> Bool
130all = Native.List.all
132{-| Check to see if any elements satisfy the predicate. -}
133any : (a -> Bool) -> [a] -> Bool
134any = Native.List.any
136{-| Check to see if all elements are True. -}
137and : [Bool] -> Bool
138and = foldl (&&) True
140{-| Check to see if any elements are True. -}
141or : [Bool] -> Bool
142or = foldl (||) False
144{-| Concatenate a list of appendable things:
146 concat [[1,2],[3],[4,5]] == [1,2,3,4,5]
147 concat ["tree","house"] == "treehouse"
148-}
149concat : [appendable] -> appendable
150concat = Native.List.concat
152{-| Map a given function onto a list and flatten the resulting lists.
154 concatMap f xs == concat (map f xs)
155-}
156concatMap : (a -> appendable) -> [a] -> appendable
157concatMap f list = concat (map f list)
159{-| Get the sum of the list elements. `(sum [1..4] == 10)` -}
160sum : [number] -> number
161sum = foldl (+) 0
163{-| Get the product of the list elements. `(product [1..4] == 24)` -}
164product : [number] -> number
165product = foldl (*) 1
167{-| Find the maximum element in a non-empty list: `maximum [1,4,2] == 4` -}
168maximum : [comparable] -> comparable
169maximum = foldl1 max
171{-| Find the minimum element in a non-empty list: `minimum [3,2,1] == 1` -}
172minimum : [comparable] -> comparable
173minimum = foldl1 min
175{-| Partition a list based on a predicate. The first list contains all values
176that satisfy the predicate, and the second list contains all the value that do
177not.
179 partition (\x -> x < 3) [0..5] == ([0,1,2], [3,4,5])
180 partition isEven [0..5] == ([0,2,4], [1,3,5])
181-}
182partition : (a -> Bool) -> [a] -> ([a],[a])
183partition pred =
184 let step x (ts, fs) = if pred x
185 then (x::ts, fs)
186 else (ts, x::fs)
187 in foldr step ([],[])
189{-| Combine two lists, combining them into tuples pairwise.
190If one list is longer, the extra elements are dropped.
192 zip [1,2,3] [6,7] == [(1,6),(2,7)]
193 zip == zipWith (,)
194-}
195zip : [a] -> [b] -> [(a,b)]
196zip = Native.List.zip
198zip3 : [a] -> [b] -> [c] -> [(a,b,c)]
199zip3 = Native.List.zipWith3 (,,)
201zip4 : [a] -> [b] -> [c] -> [d] -> [(a,b,c,d)]
202zip4 = Native.List.zipWith4 (,,,)
204zip5 : [a] -> [b] -> [c] -> [d] -> [e] -> [(a,b,c,d,e)]
205zip5 = Native.List.zipWith5 (,,,,)
207{-| Combine two lists, combining them with the given function.
208If one list is longer, the extra elements are dropped.
210 zipWith (+) [1,2,3] [1,2,3,4] == [2,4,6]
211-}
212zipWith : (a -> b -> c) -> [a] -> [b] -> [c]
213zipWith = Native.List.zipWith
215zipWith3 : (a -> b -> c -> x) -> [a] -> [b] -> [c] -> [x]
216zipWith3 = Native.List.zipWith3
218zipWith4 : (a -> b -> c -> d -> x) -> [a] -> [b] -> [c] -> [d] -> [x]
219zipWith4 = Native.List.zipWith4
221zipWith5 : (a -> b -> c -> d -> e -> x) -> [a] -> [b] -> [c] -> [d] -> [e] -> [x]
222zipWith5 = Native.List.zipWith5
224{-| Decompose a list of tuples.
226 unzip [(0, True), (17, False), (1337, True)] == ([0,17,1337], [True,False,True])
227-}
228unzip : [(a,b)] -> ([a],[b])
229unzip =
230 let step (x,y) (xs, ys) = (x::xs, y::ys)
231 in foldr step ([], [])
233{-| Places the given value between all of the lists in the second
234argument and concatenates the result.
236 join "a" ["H","w","ii","n"] == "Hawaiian"
237-}
238join : appendable -> [appendable] -> appendable
239join = Native.List.join
241{-| Places the given value between all members of the given list.
243 intersperse "on" ["turtles","turtles","turtles"] == ["turtles","on","turtles","on","turtles"]
244-}
245intersperse : a -> [a] -> [a]
246intersperse sep xs =
247 case xs of
248 [] -> []
249 hd::tl ->
250 let step x rest = sep :: x :: rest
251 spersed = foldr step [] tl
252 in hd :: spersed
254{-| Take the first n members of a list: `(take 2 [1,2,3,4] == [1,2])` -}
255take : Int -> [a] -> [a]
256take = Native.List.take
258{-| Drop the first n members of a list: `(drop 2 [1,2,3,4] == [3,4])` -}
259drop : Int -> [a] -> [a]
260drop = Native.List.drop
262{-| Creates a list with *n* copies of a value:
263`(repeat 3 (0,0) == [(0,0),(0,0),(0,0)]`
264-}
265repeat : Int -> a -> [a]
266repeat = Native.List.repeat
268{-| Sort values from lowest to highest: `sort [3,1,5] == [1,3,5]`
269-}
270sort : [comparable] -> [comparable]
271sort = Native.List.sort
273{-| Sort values by a derived property.
275```haskell
276alice = { name="Alice", height=1.62 }
277bob = { name="Bob" , height=1.85 }
278chuck = { name="Chuck", height=1.76 }
280sortBy .name [chuck,alice,bob] == [alice,bob,chuck]
281sortBy .height [chuck,alice,bob] == [alice,chuck,bob]
283sortBy String.length ["mouse","cat"] == ["cat","mouse"]
284```
285-}
286sortBy : (a -> comparable) -> [a] -> [a]
287sortBy = Native.List.sortBy
289{-| Sort values with a custom comparison function.
291```haskell
292sortWith flippedComparison [1..5] == [5,4,3,2,1]
294flippedComparison a b =
295 case compare a b of
296 LT -> GT
297 EQ -> EQ
298 GT -> LT
299```
301This is also the most general sort function, allowing you
302to define any other: `sort == sortWith compare`
303-}
304sortWith : (a -> a -> Order) -> [a] -> [a]
305sortWith = Native.List.sortWith