elm-community/list-extra/5.0.0

NOTE: this package is not compatible with Elm 0.19.1

List.Extra

Convenience functions for working with List

Basics

last : List a -> Maybe a

Extract the last element of a list.

last [1,2,3] == Just 3
last [] == Nothing
init : List a -> Maybe (List a)

Return all elements of the list except the last one.

init [1,2,3] == Just [1,2]
init [] == Nothing
getAt : Int -> List a -> Maybe a

Returns Just the element at the given index in the list, or Nothing if the index is out of range.

(!!) : List a -> Int -> Maybe a

Alias for getAt, but with the parameters flipped.

uncons : List a -> Maybe ( a, List a )

Decompose a list into its head and tail. If the list is empty, return Nothing. Otherwise, return Just (x, xs), where x is head and xs is tail.

uncons [1,2,3] == Just (1, [2,3])
uncons [] = Nothing
maximumBy : (a -> comparable) -> List a -> Maybe a

Find the first maximum element in a list using a comparable transformation

minimumBy : (a -> comparable) -> List a -> Maybe a

Find the first minimum element in a list using a comparable transformation

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

Map functions taking multiple arguments over multiple lists. Each list should be of the same length.

((\a b c -> a + b * c)
    |> map [1,2,3]
    |> andMap [4,5,6]
    |> andMap [2,1,1]
) == [9,7,9]
andThen : (a -> List b) -> List a -> List b

Equivalent to concatMap. For example, suppose you want to have a cartesian product of [1,2] and [3,4]:

[1,2] |> andThen (\x -> [3,4]
      |> andThen (\y -> [(x,y)]))

will give back the list:

[(1,3),(1,4),(2,3),(2,4)]

Now suppose we want to have a cartesian product between the first list and the second list and its doubles:

[1,2] |> andThen (\x -> [3,4]
      |> andThen (\y -> [y,y*2]
      |> andThen (\z -> [(x,z)])))

will give back the list:

[(1,3),(1,6),(1,4),(1,8),(2,3),(2,6),(2,4),(2,8)]

Advanced functional programmers will recognize this as the implementation of bind operator (>>=) for lists from the Monad typeclass.

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

Take elements in order as long as the predicate evaluates to True

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

Drop elements in order as long as the predicate evaluates to True

unique : List comparable -> List comparable

Remove duplicate values, keeping the first instance of each element which appears more than once.

unique [0,1,1,0,1] == [0,1]
uniqueBy : (a -> comparable) -> List a -> List a

Drop duplicates where what is considered to be a duplicate is the result of first applying the supplied function to the elements of the list.

allDifferent : List comparable -> Bool

Indicate if list has duplicate values.

allDifferent [0,1,1,0,1] == False
allDifferentBy : (a -> comparable) -> List a -> Bool

Indicate if list has duplicate values when supplied function are applyed on each values.

replaceIf : (a -> Bool) -> a -> List a -> List a

Replace all values that satisfy a predicate with a replacement value.

setAt : Int -> a -> List a -> Maybe (List a)

Set a value in a list by index. Returns the updated list if the index is in range, or Nothing if it is out of range.

remove : a -> List a -> List a

Remove the first occurrence of a value from a list.

updateIf : (a -> Bool) -> (a -> a) -> List a -> List a

Replace all values that satisfy a predicate by calling an update function.

updateAt : Int -> (a -> a) -> List a -> Maybe (List a)

Replace a value at a specific index by calling an update function.

updateIfIndex : (Int -> Bool) -> (a -> a) -> List a -> List a

Replace a value at an index that satisfies a predicate.

singleton : a -> List a

Convert a value to a list containing one value.

singleton 3 == [3]
removeAt : Int -> List a -> List a

Remove the element at an index from a list. If the index is out of range, this returns the original list unchanged. Otherwise, it returns the updated list.

filterNot : (a -> Bool) -> List a -> List a

Take a predicate and a list, and return a list that contains elements which fails to satisfy the predicate. This is equivalent to List.filter (not << predicate) list.

filterNot isEven [1,2,3,4] == [1,3]
swapAt : Int -> Int -> List a -> Maybe (List a)

Swap two values in a list by index. Returns the updated list if both indices are in range, or Nothing if both are out of range. If the same index is supplied twice the original list is returned.

stableSortWith : (a -> a -> Order) -> List a -> List a

Similar to List.sortWith, this sorts values with a custom comparison function. Unlike List.sortWith, this sort is guaranteed to be a stable sort. Note that List.sortWith is faster and is preferred if sort stability is not required.

List transformations

intercalate : List a -> List (List a) -> List a

Take a list and a list of lists, insert that list between every list in the list of lists, concatenate the result. intercalate xs xss is equivalent to concat (intersperse xs xss).

intercalate [0,0] [[1,2],[3,4],[5,6]] == [1,2,0,0,3,4,0,0,5,6]
transpose : List (List a) -> List (List a)

Transpose rows and columns of the list of lists.

transpose [[1,2,3],[4,5,6]] == [[1,4],[2,5],[3,6]]

If some rows are shorter than the following rows, their elements are skipped:

transpose [[10,11],[20],[],[30,31,32]] == [[10,20,30],[11,31],[32]]
subsequences : List a -> List (List a)

Return the list of all subsequences of a list.

subsequences [1,2,3] == [[],[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3]]
permutations : List a -> List (List a)

Return the list of of all permutations of a list. The result is in lexicographic order.

permutations [1,2,3] == [[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
interweave : List a -> List a -> List a

Return a list that contains elements from the two provided, in alternate order. If one list runs out of items, append the items from the remaining list.

interweave [1,3] [2,4] == [1,2,3,4]
interweave [1,3,5,7] [2,4] == [1,2,3,4,5,7]

Folds

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

Variant of foldl that has no starting value argument and treats the head of the list as its starting value. If the list is empty, return Nothing.

foldl1 max [1,2,3,2,1] == Just 3
foldl1 max [] == Nothing
foldl1 (-) [1,2,3] == Just -4
foldr1 : (a -> a -> a) -> List a -> Maybe a

Variant of foldr that has no starting value argument and treats the last element of the list as its starting value. If the list is empty, return Nothing.

foldr1 min [1,2,3,2,1] == Just 1
foldr1 min [] == Nothing
foldr1 (-) [1,2,3] == Just 2
indexedFoldl : (Int -> a -> b -> b) -> b -> List a -> b

Variant of foldl that passes the index of the current element to the step function. indexedFoldl is to List.foldl as List.indexedMap is to List.map.

indexedFoldr : (Int -> a -> b -> b) -> b -> List a -> b

Variant of foldr that passes the index of the current element to the step function. indexedFoldr is to List.foldr as List.indexedMap is to List.map.

Building lists

scanl1 : (a -> a -> a) -> List a -> List a

scanl1 is a variant of scanl that has no starting value argument.

Compare:

List.scanl (+) 0 [1,2,3] == [0,1,3,6]
scanl1 (+) [1,2,3] == [1,3,6]


List.scanl (-) 0 [1,2,3] == [0,1,1,2]
scanl1 (-) [1,2,3] == [1,1,2]


List.scanl (flip (-)) 0 [1,2,3] == [0,-1,-3,-6]
scanl1 (flip (-)) [1,2,3] == [1,-1,-4]
scanr : (a -> b -> b) -> b -> List a -> List b

scanr is a right-to-left dual of scanl. Note that:

head (scanr f z xs) == foldr f z xs

Examples:

scanr (+) 0 [1,2,3] == [6,5,3,0]
scanr (-) 0 [1,2,3] == [2,-1,3,0]
scanr1 : (a -> a -> a) -> List a -> List a

scanr1 is a variant of scanr that has no starting value argument.

scanr1 (+) [1,2,3] == [6,5,3]
scanr1 (-) [1,2,3] == [2,-1,3]
scanr1 (flip (-)) [1,2,3] == [0,1,3]
unfoldr : (b -> Maybe ( a, b )) -> b -> List a

The unfoldr function is "dual" to foldr. foldr reduces a list to a summary value, unfoldr builds a list from a seed. The function takes a function and a starting element. It applies the function to the element. If the result is Just (a, b), a is accumulated and the function is applied to b. If the result is Nothing, the list accumulated so far is returned.

unfoldr (\b -> if b == 0 then Nothing else Just (b, b-1)) 5 == [5,4,3,2,1]
iterate : (a -> Maybe a) -> a -> List a

Returns a list of repeated applications of f.

If f returns Nothing the iteration will stop. If it returns Just y then y will be added to the list and the iteration will continue with f y. nextYear : Int -> Maybe Int nextYear year = if year >= 2030 then Nothing else Just (year + 1) -- Will evaluate to [2010, 2011, ..., 2030] iterate nextYear 2010

Sublists

splitAt : Int -> List a -> ( List a, List a )

Take a number and a list, return a tuple of lists, where first part is prefix of the list of length equal the number, and second part is the remainder of the list. splitAt n xs is equivalent to (take n xs, drop n xs).

splitAt 3 [1,2,3,4,5] == ([1,2,3],[4,5])
splitAt 1 [1,2,3] == ([1],[2,3])
splitAt 3 [1,2,3] == ([1,2,3],[])
splitAt 4 [1,2,3] == ([1,2,3],[])
splitAt 0 [1,2,3] == ([],[1,2,3])
splitAt (-1) [1,2,3] == ([],[1,2,3])
takeWhileRight : (a -> Bool) -> List a -> List a

Take elements from the right, while predicate still holds.

takeWhileRight ((<)5) (range 1 10) == [6,7,8,9,10]
dropWhileRight : (a -> Bool) -> List a -> List a

Drop elements from the right, while predicate still holds.

dropWhileRight ((<)5) (range 1 10) == [1,2,3,4,5]
span : (a -> Bool) -> List a -> ( List a, List a )

Take a predicate and a list, return a tuple. The first part of the tuple is the longest prefix of that list, for each element of which the predicate holds. The second part of the tuple is the remainder of the list. span p xs is equivalent to (takeWhile p xs, dropWhile p xs).

span ((>) 3) [1,2,3,4,1,2,3,4] == ([1,2],[3,4,1,2,3,4])
span ((>) 5) [1,2,3] == ([1,2,3],[])
span ((>) 0) [1,2,3] == ([],[1,2,3])
break : (a -> Bool) -> List a -> ( List a, List a )

Take a predicate and a list, return a tuple. The first part of the tuple is the longest prefix of that list, for each element of which the predicate does not hold. The second part of the tuple is the remainder of the list. break p xs is equivalent to (takeWhile (not p) xs, dropWhile (not p) xs).

break ((<) 3) [1,2,3,4,1,2,3,4] == ([1,2,3],[4,1,2,3,4])
break ((>) 5) [1,2,3] == ([],[1,2,3])
break ((<) 5) [1,2,3] == ([1,2,3],[])
stripPrefix : List a -> List a -> Maybe (List a)

Drop the given prefix from the list. If the list doesn't start with that prefix, return Nothing.

stripPrefix [1,2] [1,2,3,4] == Just [3,4]
stripPrefix [1,2,3] [1,2,3,4,5] == Just [4,5]
stripPrefix [1,2,3] [1,2,3] == Just []
stripPrefix [1,2,3] [1,2] == Nothing
stripPrefix [3,2,1] [1,2,3,4,5] == Nothing
group : List a -> List (List a)

Group similar elements together. group is equivalent to groupWhile (==).

group [1,2,2,3,3,3,2,2,1] == [[1],[2,2],[3,3,3],[2,2],[1]]
groupWhile : (a -> a -> Bool) -> List a -> List (List a)

Group elements together, using a custom equality test.

groupWhile (\x y -> first x == first y) [(0,'a'),(0,'b'),(1,'c'),(1,'d')] == [[(0,'a'),(0,'b')],[(1,'c'),(1,'d')]]

The equality test should be an equivalent relationship, i.e. it should have the properties of reflexivity, symmetry, and transitivity. For non-equivalent relations it gives non-intuitive behavior:

groupWhile (<) [1,2,3,2,4,1,3,2,1] == [[1,2,3,2,4],[1,3,2],[1]]

For grouping elements with a comparison test, which must only hold the property of transitivity, see groupWhileTransitively.

groupWhileTransitively : (a -> a -> Bool) -> List a -> List (List a)

Group elements together, using a custom comparison test. Start a new group each time the comparison test doesn't hold for two adjacent elements.

groupWhileTransitively (<) [1,2,3,2,4,1,3,2,1] == [[1,2,3],[2,4],[1,3],[2],[1]]
inits : List a -> List (List a)

Return all initial segments of a list, from shortest to longest, empty list first, the list itself last.

inits [1,2,3] == [[],[1],[1,2],[1,2,3]]
tails : List a -> List (List a)

Return all final segments of a list, from longest to shortest, the list itself first, empty list last.

tails [1,2,3] == [[1,2,3],[2,3],[3],[]]
select : List a -> List ( a, List a )

Return all combinations in the form of (element, rest of the list). Read Haskell Libraries proposal for further ideas on how to use this function.

select [1,2,3,4] == [(1,[2,3,4]),(2,[1,3,4]),(3,[1,2,4]),(4,[1,2,3])]
selectSplit : List a -> List ( List a, a, List a )

Return all combinations in the form of (elements before, element, elements after).

selectSplit [1,2,3] == [([],1,[2,3]),([1],2,[3]),([1,2],3,[])]

Predicates

isPrefixOf : List a -> List a -> Bool

Take 2 lists and return True, if the first list is the prefix of the second list.

isSuffixOf : List a -> List a -> Bool

Take 2 lists and return True, if the first list is the suffix of the second list.

isInfixOf : List a -> List a -> Bool

Take 2 lists and return True, if the first list is an infix of the second list.

isSubsequenceOf : List a -> List a -> Bool

Take 2 lists and return True, if the first list is a subsequence of the second list.

isPermutationOf : List a -> List a -> Bool

Take 2 lists and return True, if the first list is a permutation of the second list.

Searching

notMember : a -> List a -> Bool

Negation of member.

notMember 1 [1,2,3] == False
notMember 4 [1,2,3] == True
find : (a -> Bool) -> List a -> Maybe a

Find the first element that satisfies a predicate and return Just that element. If none match, return Nothing.

find (\num -> num > 5) [2, 4, 6, 8] == Just 6
elemIndex : a -> List a -> Maybe Int

Return the index of the first occurrence of the element. Otherwise, return Nothing. Indexing starts from 0.

elemIndex 1 [1,2,3] == Just 0
elemIndex 4 [1,2,3] == Nothing
elemIndex 1 [1,2,1] == Just 0
elemIndices : a -> List a -> List Int

Return all indices of occurrences of the element. If element is not found, return empty list. Indexing starts from 0.

elemIndices 1 [1,2,3] == [0]
elemIndices 4 [1,2,3] == []
elemIndices 1 [1,2,1] == [0,2]
findIndex : (a -> Bool) -> List a -> Maybe Int

Take a predicate and a list, return the index of the first element that satisfies the predicate. Otherwise, return Nothing. Indexing starts from 0.

findIndex isEven [1,2,3] == Just 1
findIndex isEven [1,3,5] == Nothing
findIndex isEven [1,2,4] == Just 1
findIndices : (a -> Bool) -> List a -> List Int

Take a predicate and a list, return indices of all elements satisfying the predicate. Otherwise, return empty list. Indexing starts from 0.

findIndices isEven [1,2,3] == [1]
findIndices isEven [1,3,5] == []
findIndices isEven [1,2,4] == [1,2]

Zipping

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

Take two lists and returns a list of corresponding pairs

zip3 : List a -> List b -> List c -> List ( a, b, c )

Take three lists and returns a list of triples

zip4 : List a -> List b -> List c -> List d -> List ( a, b, c, d )

Take four lists and returns a list of quadruples

zip5 : List a -> List b -> List c -> List d -> List e -> List ( a, b, c, d, e )

Take five lists and returns a list of quintuples

Lift functions onto multiple lists of arguments

lift2 : (a -> b -> c) -> List a -> List b -> List c

Map functions taking multiple arguments over multiple lists, regardless of list length. All possible combinations will be explored.

lift2 (+) [1,2,3] [4,5] == [5,6,6,7,7,8]

lift3 : (a -> b -> c -> d) -> List a -> List b -> List c -> List d
lift4 : (a -> b -> c -> d -> e) -> List a -> List b -> List c -> List d -> List e

Split to groups of given size

groupsOf : Int -> List a -> List (List a)

Split list into groups of size given by the first argument.

groupsOf 3 (range 1 10) == [[1,2,3],[4,5,6],[7,8,9]]
groupsOfWithStep : Int -> Int -> List a -> List (List a)

Split list into groups of size given by the first argument. After each group, drop a number of elements given by the second argument before starting the next group.

groupsOfWithStep 2 1 (range 1 4) == [[1,2],[2,3],[3,4]]
groupsOfVarying : List Int -> List a -> List (List a)

groupsOfVarying ns takes n elements from a list for each n in ns, splitting the list into variably sized segments

groupsOfVarying [2, 3, 1] ["a", "b", "c", "d", "e", "f"] == [["a", "b"], ["c", "d", "e"], ["f"]]
groupsOfVarying [2] ["a", "b", "c", "d", "e", "f"] == [["a", "b"]]
groupsOfVarying [2, 3, 1, 5, 6] ["a", "b", "c", "d", "e"] == [["a", "b"], ["c", "d", "e"]]
greedyGroupsOf : Int -> List a -> List (List a)

Split list into groups of size given by the first argument "greedily" (don't throw the group away if not long enough).

greedyGroupsOf 3 (range 1 10) == [[1,2,3],[4,5,6],[7,8,9],[10]]
greedyGroupsOfWithStep : Int -> Int -> List a -> List (List a)

Split list into groups of size given by the first argument "greedily" (don't throw the group away if not long enough). After each group, drop a number of elements given by the second argumet before starting the next group.

greedyGroupsOfWithStep 3 2 (range 1 6) == [[1,2,3],[3,4,5],[5,6]]