@@ -1,131 +1,162 @@
2module List where
1module List where
3+{-| A library for manipulating lists of values. Every value in a
4+list must have the same type.
7+@docs (::), (++), length, reverse, map
10+@docs head, tail, last, filter, take, drop
12+# Putting Lists Together
13+@docs concat, concatMap, join, intersperse, zip, zipWith
16+@docs split, partition, unzip
19+@docs foldr, foldl, foldr1, foldl1, scanl, scanl1
22+@docs susm, product, maximum, minimum, all, any, and, or
4import open Basics
25import open Basics
5import Native.List
26import Native.List
7−-- Add an element to the front of a list `(1 :: [2,3] == [1,2,3])`
28+{-| Add an element to the front of a list `(1 :: [2,3] == [1,2,3])` -}
8(::) : a -> [a] -> [a]
29(::) : a -> [a] -> [a]
9(::) = Native.List.cons
30(::) = Native.List.cons
11−-- Puts two appendable things together:
32+{-| Puts two appendable things together:
13−-- [1,1] ++ [2,3] == [1,1,2,3]
34+ [1,1] ++ [2,3] == [1,1,2,3]
14−-- "abc" ++ "123" == "abc123"
35+ "abc" ++ "123" == "abc123"
15(++) : appendable -> appendable -> appendable
37(++) : appendable -> appendable -> appendable
16(++) = Native.List.append
38(++) = Native.List.append
18−-- Extract the first element of a list. List must be non-empty.
40+{-| Extract the first element of a list. List must be non-empty.
19−-- `(head [1,2,3] == 1)`
41+`(head [1,2,3] == 1)`
20head : [a] -> a
43head : [a] -> a
21head = Native.List.head
44head = Native.List.head
23−-- Extract the elements after the head of the list. List must be non-empty.
46+{-| Extract the elements after the head of the list. List must be non-empty.
24−-- `(tail [1,2,3] == [2,3])`
47+`(tail [1,2,3] == [2,3])`
25tail : [a] -> [a]
49tail : [a] -> [a]
26tail = Native.List.tail
50tail = Native.List.tail
28−-- Extract the last element of a list. List must be non-empty.
52+{-| Extract the last element of a list. List must be non-empty.
29−-- `(last [1,2,3] == 3)`
53+`(last [1,2,3] == 3)`
30last : [a] -> a
55last : [a] -> a
31last = Native.List.last
56last = Native.List.last
33−-- Check if a list is empty `(isEmpty [] == True)`
58+{-| Check if a list is empty `(isEmpty [] == True)` -}
34isEmpty : [a] -> Bool
59isEmpty : [a] -> Bool
35isEmpty xs =
60isEmpty xs =
36 case xs of
61 case xs of
37 [] -> True
62 [] -> True
38 _ -> False
63 _ -> False
40−-- Apply a function to every element of a list: `(map sqrt [1,4,9] == [1,2,3])`
65+{-| Apply a function to every element of a list: `(map sqrt [1,4,9] == [1,2,3])` -}
41map : (a -> b) -> [a] -> [b]
66map : (a -> b) -> [a] -> [b]
42map = Native.List.map
67map = Native.List.map
44−-- Reduce a list from the left: `(foldl (::) [] "gateman" == "nametag")`
69+{-| Reduce a list from the left: `(foldl (::) [] "gateman" == "nametag")` -}
45foldl : (a -> b -> b) -> b -> [a] -> b
70foldl : (a -> b -> b) -> b -> [a] -> b
46foldl = Native.List.foldl
71foldl = Native.List.foldl
48−-- Reduce a list from the right: `(foldr (+) 0 [1,2,3] == 6)`
73+{-| Reduce a list from the right: `(foldr (+) 0 [1,2,3] == 6)` -}
49foldr : (a -> b -> b) -> b -> [a] -> b
74foldr : (a -> b -> b) -> b -> [a] -> b
50foldr = Native.List.foldr
75foldr = Native.List.foldr
52−-- Reduce a list from the left without a base case. List must be non-empty.
77+{-| Reduce a list from the left without a base case. List must be non-empty. -}
53foldl1 : (a -> a -> a) -> [a] -> a
78foldl1 : (a -> a -> a) -> [a] -> a
54foldl1 = Native.List.foldl1
79foldl1 = Native.List.foldl1
56−-- Reduce a list from the right without a base case. List must be non-empty.
81+{-| Reduce a list from the right without a base case. List must be non-empty. -}
57foldr1 : (a -> a -> a) -> [a] -> a
82foldr1 : (a -> a -> a) -> [a] -> a
58foldr1 = Native.List.foldr1
83foldr1 = Native.List.foldr1
60−-- Reduce a list from the left, building up all of the intermediate results into a list.
85+{-| Reduce a list from the left, building up all of the intermediate results into a list.
62−-- scanl (+) 0 [1,2,3,4] == [0,1,3,6,10]
87+ scanl (+) 0 [1,2,3,4] == [0,1,3,6,10]
63scanl : (a -> b -> b) -> b -> [a] -> [b]
89scanl : (a -> b -> b) -> b -> [a] -> [b]
64scanl = Native.List.scanl
90scanl = Native.List.scanl
66−-- Same as scanl but it doesn't require a base case. List must be non-empty.
92+{-| Same as scanl but it doesn't require a base case. List must be non-empty.
68−-- scanl1 (+) [1,2,3,4] == [1,3,6,10]
94+ scanl1 (+) [1,2,3,4] == [1,3,6,10]
69scanl1 : (a -> a -> a) -> [a] -> [a]
96scanl1 : (a -> a -> a) -> [a] -> [a]
70scanl1 = Native.List.scanl1
97scanl1 = Native.List.scanl1
72−-- Filter out elements which do not satisfy the predicate: `(filter isLower "AaBbCc" == "abc")`
99+{-| Keep only elements that satisfy the predicate:
100+`(filter isLower "AaBbCc" == "abc")`
73filter : (a -> Bool) -> [a] -> [a]
102filter : (a -> Bool) -> [a] -> [a]
74filter = Native.List.filter
103filter = Native.List.filter
76−-- Determine the length of a list: `(length "innumerable" == 11)`
105+{-| Determine the length of a list: `(length "innumerable" == 11)` -}
77length : [a] -> Int
106length : [a] -> Int
78length = Native.List.length
107length = Native.List.length
80−-- Reverse a list. `(reverse [1..4] == [4,3,2,1])`
109+{-| Reverse a list. `(reverse [1..4] == [4,3,2,1])` -}
81reverse : [a] -> [a]
110reverse : [a] -> [a]
82reverse = Native.List.reverse
111reverse = Native.List.reverse
84−-- Check to see if all elements satisfy the predicate.
113+{-| Check to see if all elements satisfy the predicate. -}
85all : (a -> Bool) -> [a] -> Bool
114all : (a -> Bool) -> [a] -> Bool
86all = Native.List.all
115all = Native.List.all
88−-- Check to see if any elements satisfy the predicate.
117+{-| Check to see if any elements satisfy the predicate. -}
89any : (a -> Bool) -> [a] -> Bool
118any : (a -> Bool) -> [a] -> Bool
90any = Native.List.any
119any = Native.List.any
92−-- Check to see if all elements are True.
121+{-| Check to see if all elements are True. -}
93and : [Bool] -> Bool
122and : [Bool] -> Bool
94and = foldl (&&) True
123and = foldl (&&) True
96−-- Check to see if any elements are True.
125+{-| Check to see if any elements are True. -}
97or : [Bool] -> Bool
126or : [Bool] -> Bool
98or = foldl (||) False
127or = foldl (||) False
100−-- Concatenate a list of appendable things:
129+{-| Concatenate a list of appendable things:
102−-- concat ["tree","house"] == "treehouse"
131+ concat ["tree","house"] == "treehouse"
103concat : [appendable] -> appendable
133concat : [appendable] -> appendable
104concat = Native.List.concat
134concat = Native.List.concat
106−-- Map a given function onto a list and flatten the resulting lists.
136+{-| Map a given function onto a list and flatten the resulting lists.
108−-- concatMap f xs == concat (map f xs)
138+ concatMap f xs == concat (map f xs)
109concatMap : (a -> appendable) -> [a] -> appendable
140concatMap : (a -> appendable) -> [a] -> appendable
110concatMap f list = concat (map f list)
141concatMap f list = concat (map f list)
112−-- Get the sum of the list elements. `(sum [1..4] == 10)`
143+{-| Get the sum of the list elements. `(sum [1..4] == 10)` -}
113sum : [number] -> number
144sum : [number] -> number
114sum = foldl (+) 0
145sum = foldl (+) 0
116−-- Get the product of the list elements. `(product [1..4] == 24)`
147+{-| Get the product of the list elements. `(product [1..4] == 24)` -}
117product : [number] -> number
148product : [number] -> number
118product = foldl (*) 1
149product = foldl (*) 1
120−-- Find the maximum element in a non-empty list: `maximum [1,4,2] == 4`
151+{-| Find the maximum element in a non-empty list: `maximum [1,4,2] == 4` -}
121maximum : [comparable] -> comparable
152maximum : [comparable] -> comparable
122maximum = foldl1 max
153maximum = foldl1 max
124−-- Find the minimum element in a non-empty list: `minimum [3,2,1] == 1`
155+{-| Find the minimum element in a non-empty list: `minimum [3,2,1] == 1` -}
125minimum : [comparable] -> comparable
156minimum : [comparable] -> comparable
126minimum = foldl1 min
157minimum = foldl1 min
128−-- Split a list based on the predicate.
159+{-| Split a list based on the predicate. -}
129partition : (a -> Bool) -> [a] -> ([a],[a])
160partition : (a -> Bool) -> [a] -> ([a],[a])
130partition pred lst =
161partition pred lst =
131 case lst of
162 case lst of
@@ -133,44 +164,49 @@ partition pred lst =
133 x::xs -> let (bs,cs) = partition pred xs in
164 x::xs -> let (bs,cs) = partition pred xs in
134 if pred x then (x::bs,cs) else (bs,x::cs)
165 if pred x then (x::bs,cs) else (bs,x::cs)
136−-- Combine two lists, combining them into tuples pairwise.
167+{-| Combine two lists, combining them into tuples pairwise.
137−-- If one list is longer, the extra elements are dropped.
168+If one list is longer, the extra elements are dropped.
139−-- zip [1,2,3] [6,7] == [(1,6),(2,7)]
170+ zip [1,2,3] [6,7] == [(1,6),(2,7)]
140−-- zip == zipWith (,)
171+ zip == zipWith (,)
141zip : [a] -> [b] -> [(a,b)]
173zip : [a] -> [b] -> [(a,b)]
142zip = Native.List.zip
174zip = Native.List.zip
144−-- Combine two lists, combining them with the given function.
176+{-| Combine two lists, combining them with the given function.
145−-- If one list is longer, the extra elements are dropped.
177+If one list is longer, the extra elements are dropped.
147−-- zipWith (+) [1,2,3] [1,2,3,4] == [2,4,6]
179+ zipWith (+) [1,2,3] [1,2,3,4] == [2,4,6]
148zipWith : (a -> b -> c) -> [a] -> [b] -> [c]
181zipWith : (a -> b -> c) -> [a] -> [b] -> [c]
149zipWith = Native.List.zipWith
182zipWith = Native.List.zipWith
151−-- Decompose a list of tuples.
184+{-| Decompose a list of tuples. -}
152unzip : [(a,b)] -> ([a],[b])
185unzip : [(a,b)] -> ([a],[b])
153unzip pairs =
186unzip pairs =
154 case pairs of
187 case pairs of
155 [] -> ([],[])
188 [] -> ([],[])
156 (x,y)::ps -> let (xs,ys) = (unzip ps) in (x::xs,y::ys)
189 (x,y)::ps -> let (xs,ys) = (unzip ps) in (x::xs,y::ys)
158−-- Split a list with a given seperator.
191+{-| Split a list with a given seperator.
160−-- split "," "hello,there,friend" == ["hello", "there", "friend"]
193+ split "," "hello,there,friend" == ["hello", "there", "friend"]
161split : [a] -> [a] -> [[a]]
195split : [a] -> [a] -> [[a]]
162split = Native.List.split
196split = Native.List.split
164−-- Places the given value between all of the lists in the second argument
198+{-| Places the given value between all of the lists in the second
165−-- and concatenates the result.
199+argument and concatenates the result.
167−-- join "a" ["H","w","ii","n"] == "Hawaiian"
201+ join "a" ["H","w","ii","n"] == "Hawaiian"
168join : appendable -> [appendable] -> appendable
203join : appendable -> [appendable] -> appendable
169join = Native.List.join
204join = Native.List.join
171−-- Places the given value between all members of the given list.
206+{-| Places the given value between all members of the given list.
173−-- intersperse ' ' "INCEPTION" == "I N C E P T I O N"
208+ intersperse ' ' "INCEPTION" == "I N C E P T I O N"
174intersperse : a -> [a] -> [a]
210intersperse : a -> [a] -> [a]
175intersperse sep xs =
211intersperse sep xs =
176 case xs of
212 case xs of
@@ -178,14 +214,16 @@ intersperse sep xs =
178 [a] -> [a]
214 [a] -> [a]
181−-- Take the first n members of a list: `(take 2 [1,2,3,4] == [1,2])`
217+{-| Take the first n members of a list: `(take 2 [1,2,3,4] == [1,2])` -}
182take : Int -> [a] -> [a]
218take : Int -> [a] -> [a]
183take = Native.List.take
219take = Native.List.take
185−-- Drop the first n members of a list: `(drop 2 [1,2,3,4] == [3,4])`
221+{-| Drop the first n members of a list: `(drop 2 [1,2,3,4] == [3,4])` -}
186drop : Int -> [a] -> [a]
222drop : Int -> [a] -> [a]
187drop = Native.List.drop
223drop = Native.List.drop
189−-- Creates a list with n copies of a value: `(replicate 3 (0,0) == [(0,0),(0,0),(0,0)]`
225+{-| Creates a list with *n* copies of a value:
226+`(repeat 3 (0,0) == [(0,0),(0,0),(0,0)]`
190repeat : Int -> a -> [a]
228repeat : Int -> a -> [a]
191repeat = Native.List.repeat
229repeat = Native.List.repeat