@@ -10,16 +10,19 @@ list must have the same type.
1010@docs head, tail, last, filter, take, drop
1111
1212# Putting Lists Together
13−@docs concat, concatMap, join, intersperse, zip, zipWith, repeat
13+@docs concat, join, intersperse, zip, zipWith, repeat
1414
1515# Taking Lists Apart
1616@docs partition, unzip
1717
1818# Folds
19−@docs foldr, foldl, foldr1, foldl1, scanl, scanl1
19+@docs foldr, foldl
20+
21+# Special Maps
22+@docs filterMap, concatMap, indexedMap
2023
2124# Special Folds
22−@docs sum, product, maximum, minimum, all, any, and, or
25+@docs sum, product, maximum, minimum, all, any, foldr1, foldl1, scanl, scanl1
2326
2427# Sorting
2528@docs sort, sortBy, sortWith
@@ -35,6 +38,7 @@ possibly should be approached another way.
3538-}
3639
3740import Basics (..)
41+import Maybe ( Maybe(Just,Nothing) )
3842import Native.List
3943
4044{-| Add an element to the front of a list `(1 :: [2,3] == [1,2,3])` -}
@@ -81,6 +85,15 @@ isEmpty xs =
8185map : (a -> b) -> [a] -> [b]
8286map = Native.List.map
8387
88+{-| Same as `map` but the function is also applied to the index of each
89+element (starting at zero).
90+
91+ indexedMap (,) ["Tom","Sue","Bob"] == [ (0,"Tom"), (1,"Sue"), (2,"Bob") ]
92+-}
93+indexedMap : (Int -> a -> b) -> [a] -> [b]
94+indexedMap f xs =
95+ zipWith f [ 0 .. length xs - 1 ] xs
96+
8497{-| Reduce a list from the left: `(foldl (::) [] [1,2,3] == [3,2,1])` -}
8598foldl : (a -> b -> b) -> b -> [a] -> b
8699foldl = Native.List.foldl
@@ -117,6 +130,22 @@ scanl1 = Native.List.scanl1
117130filter : (a -> Bool) -> [a] -> [a]
118131filter = Native.List.filter
119132
133+{-| Apply a function that may succeed to all values in the list, but only keep
134+the successes.
135+
136+ toInt : String -> Maybe Int
137+
138+ filterMap toInt ["3", "4.0", "5", "hats"] == [3,5]
139+-}
140+filterMap : (a -> Maybe b) -> [a] -> [b]
141+filterMap xs = Native.List.foldr maybeCons [] xs
142+
143+maybeCons : Maybe a -> [a] -> [a]
144+maybeCons mx xs =
145+ case mx of
146+ Just x -> x :: xs
147+ Nothing -> xs
148+
120149{-| Determine the length of a list: `(length [1,2,3] == 3)` -}
121150length : [a] -> Int
122151length = Native.List.length
@@ -133,14 +162,6 @@ all = Native.List.all
133162any : (a -> Bool) -> [a] -> Bool
134163any = Native.List.any
135164
136−{-| Check to see if all elements are True. -}
137−and : [Bool] -> Bool
138−and = foldl (&&) True
139−
140−{-| Check to see if any elements are True. -}
141−or : [Bool] -> Bool
142−or = foldl (||) False
143−
144165{-| Concatenate a list of appendable things:
145166
146167 concat [[1,2],[3],[4,5]] == [1,2,3,4,5]