friedbrice / elm-teaching-tools / ElmTeachingTools.Lib.List

Extra functions to make working with lists easier.

Create lists

iterate : (a -> Maybe a) -> a -> List a

Create a list by repeatedly applying a function, stopping when the function returns Nothing.

Warning: This function can cause an infinite loop (or, more likely, a "Maximum call stack size exceeded" error).

--| Example.
iterate
    (\x ->
        if x == 3 then
            Nothing

        else
            Just (x + 1)
    )
    0
--> [1, 2, 3]

unfold : (b -> Maybe ( a, b )) -> b -> List a

A more general version of iterate. Create a list by repeatedly applying a function, stopping when the function return Nothing.

Warning: This function can cause an infinite loop (or, more likely, a "Maximum call stack size exceeded" error).

--| Example.
unfold String.uncons "slowly"
--> ['s', 'l', 'o', 'w', 'l', 'y']

--| Can simulate `iterate`.
unfold
    (\x ->
        if x == 3 then
            Nothing

        else
            Just (x + 1, x + 1)
    )
    0
--> [1, 2, 3]

--| More general than `iterate`.
unfold
    (\x ->
        if x == 3 then
            Nothing

        else
            Just (x^2, x + 1)
    )
    0
--> [0, 1, 4]

fromMaybe : Maybe a -> List a

Create either a singleton list or an empty list from a Maybe.

--| Empty maybe yields empty list.
fromMaybe Nothing
--> []

--| Populated maybe yields singleton list.
fromMaybe (Just 5)
--> [5]

Transform lists

dropWhile : (a -> Basics.Bool) -> List a -> List a

Drop elements from the front of a list until the supplied callback is false.

--| Example.
dropWhile (\x -> x < 5) [ 1, 2, 3, 4, 5, 3 ]
--> [5, 3]

takeWhile : (a -> Basics.Bool) -> List a -> List a

Take elements from the front of a list until the supplied callback is false.

--| Example.
takeWhile (\x -> x < 5) [ 1, 2, 3, 4, 5, 3 ]
--> [1, 2, 3, 4]

filterMaybes : List (Maybe a) -> List a

Filter Nothings out of a list of Maybes, unwrappig the Justs.

--| Example.
filterMaybes [ Just 1, Just 2, Nothing, Just 4 ]
--> [1, 2, 4]

Combine lists

zip : List a -> List b -> List ( a, b )

Create a list of pairs by lining two lists up. If one list is longer, the extra elements are dropped.

--| Example.
zip [ 1, 2, 3 ] [ "a", "b", "c", "d" ]
--> [(1, "a"), (2, "b"), (3, "c")]

cross : List a -> List b -> List ( a, b )

Create the list of all possible pairs from two other lists.

--| Example.
cross [ 1, 2, 3 ] [ 'a', 'b' ]
--> [(1, 'a'), (1, 'b'), (2, 'a'), (2, 'b'), (3, 'a'), (3, 'b')]

join : (a -> b -> Basics.Bool) -> List a -> List b -> List ( a, b )

Create the list of all pairs that satisfy a condition.

--| Example.
join (\x y -> even (x + y)) [1, 2, 3] [4, 5, 6]
--> [(1, 5), (2, 4), (2, 6), (3, 5)]

Use lists

inc : List a -> a -> Maybe a

Select the list element following the value you provided, if one exists.

--| Advance to next element of the list.
inc [ "do", "re", "mi" ] "re"
--> Just "mi"

--| Fails when the element does not appear in the list.
inc [ "do", "mi", "so" ] "re"
--> Nothing

--| Fails when the element appears only at the end of the list.
inc [ "do", "re", "mi" ] "mi"
--> Nothing

--| Fails when the list is empty.
inc [] "mi"
--> Nothing

dec : List a -> a -> Maybe a

Select the list element preceeding the value you provided, if one exists.

--| Go back to the previous element of the list.
dec [ "do", "re", "mi" ] "re"
--> Just "do"

--| Fails when the element does not appear in the list.
dec [ "do", "mi", "so" ] "re"
--> Nothing

--| Fails when the element appears at the beginning of the list.
dec [ "do", "re", "mi" ] "do"
--> Nothing

--| Fails when the list is empty.
dec [] "do"
--> Nothing

find : (a -> Basics.Bool) -> List a -> Maybe a

Find the first element of the list that satisfies the predicate, or an empty maybe if no list elements satisfy the predicate.

--| Finds first list element that matches.
find even [ 3, 5, 4, 1, 2 ]
--> Just 4

--| Fails if no list element matches.
find even [ 3, 5, 5, 1, 7 ]
--> Nothing

--| Fails on empty list.
find even []
--> Nothing

mapReduce : (b -> b -> b) -> b -> (a -> b) -> List a -> b

Provide a combining operation, a neutral element, and a mapping function. Maps the mapping function over a list while reducing the results using the combining function.

--| Example.
mapReduce (+) 0 String.length ["hello", "in", "TV", "land"]
--> 13

--| Can simulate `List.sum`.
mapReduce (+) 0 identity [3, 4, -2, 1]
--> 6

--| More general than `String.concat`.
mapReduce (++) "" String.fromInt [3, 4, 5, 23]
--> "34523"

--| Returns neutral element on empty list.
mapReduce (++) "" String.fromInt []
--> ""

groupBy : (a -> comparable) -> List a -> Dict comparable (List a)

Provide a key function to partition a list into sublists by key.

--| Example.
groupBy String.length ["hello", "in", "TV", "land"]
--> fromList [(2,["in","TV"]),(4,["land"]),(5,["hello"])]