coreygirard / elm-nonempty-list / List.Nonempty

A library for a non-empty list type. More obscure/specialized functions are found under Extra.

Definition


type alias ListNonempty a =
( a, List a )

A list type that must contain at least one element

Create

singleton : a -> ListNonempty a

Create a non-empty list containing just a single element

singleton 0

repeat : Basics.Int -> a -> ListNonempty a

Similar to List.repeat, except this is guaranteed to contain at least one element, regardless of the integer provided. Otherwise a Maybe return value would be required. If this behavior is desired, use List.repeat plus fromList

repeat 3 "a" |> toList == [ "a", "a", "a" ]

repeat 0 "a" |> toList == [ "a" ]

range : Basics.Int -> Basics.Int -> ListNonempty Basics.Int

Works slightly differently from List.range. First provided number will be the first number in the non-empty list, second provided number will be the last number, and it can ascend or descend.

Equivalent to List.range a b when a<=b, equal to singleton a if a>b

range 3 6 |> toList == [ 3, 4, 5, 6 ]

range 3 3 |> toList == [ 3 ]

range 6 3 |> toList == [ 6, 5, 4, 3 ]

fromPair : a -> List a -> ListNonempty a

Create a non-empty list from an element and a list.

fromPair 0 [ 1, 2, 3 ] |> toList == [ 0, 1, 2, 3 ]

Tuples

fromTuple : ( a, List a ) -> ListNonempty a

Create a non-empty list from a tuple of element and list

fromTuple ( 0, [ 1, 2, 3 ] ) |> toList == [ 0, 1, 2, 3 ]

toTuple : ListNonempty a -> ( a, List a )

Deconstruct a non-empty list into a tuple of element and list

fromTuple ( 0, [ 1, 2, 3 ] )
    |> toTuple
    == ( 0, [ 1, 2, 3 ] )

Lists

fromList : List a -> Maybe (ListNonempty a)

Try to create a non-empty list from an ordinary list. Returns Nothing if input list is empty.

fromList [ 0, 1, 2 ] == Just (fromPair 0 [ 1, 2 ])

fromList [] == Nothing

toList : ListNonempty a -> List a

Convert to a list

fromPair 0 [ 1, 2, 3 ] |> toList == [ 0, 1, 2, 3 ]

Transform

appendElem : a -> ListNonempty a -> ListNonempty a

Append a value to become the new last element.

append 4 (fromPair 1 [ 2, 3 ])
    |> toList
    == [ 1, 2, 3, 4 ]

prependElem : a -> ListNonempty a -> ListNonempty a

Prepend a value to become the new first element.

prepend 0 (fromPair 1 [ 2, 3 ])
    |> toList
    == [ 0, 1, 2, 3 ]

popFirst : ListNonempty a -> ( a, Maybe (ListNonempty a) )

Pop the first element.

fromPair 0 [ 1, 2, 3 ]
    |> popFirst
    == ( 0, Just (fromPair 1 [ 2, 3 ]) )

fromPair 0 []
    |> popFirst
    == ( 0, Nothing )

popLast : ListNonempty a -> ( Maybe (ListNonempty a), a )

Pop the last element.

fromPair 0 [ 1, 2, 3 ]
    |> popLast
    == ( 3, Just (fromPair 0 [ 1, 2 ]) )

fromPair 0 []
    |> popLast
    == ( Nothing, 0 )

map : (a -> b) -> ListNonempty a -> ListNonempty b

Equivalent to List.map

fromPair 0 [ 1, 2, 3 ]
    |> map String.fromInt
    |> toList
    == [ "0", "1", "2", "3" ]

indexedMap : (Basics.Int -> a -> b) -> ListNonempty a -> ListNonempty b

Equivalent to List.indexedMap

fromPair "a" [ "b", "c", "d" ]
    |> indexedMap Tuple.pair
    |> toList
    == [ ( 0, "a" ), ( 1, "b" ), ( 2, "c" ), ( 3, "d" ) ]

foldl : (a -> b -> b) -> b -> ListNonempty a -> b

Equivalent to List.foldl

fromPair 1 [ 2, 3 ] |> foldl (+) 0 == 6

foldl1 : (a -> a -> a) -> ListNonempty a -> a

Equivalent to List.Extra.foldl1

fromPair 1 [ 2, 3 ] |> foldl (+) 0 == 6

foldr : (a -> b -> b) -> b -> ListNonempty a -> b

Equivalent to List.foldr

fromPair 1 [ 2, 3 ] |> foldr (+) 0 == 6

foldr1 : (a -> a -> a) -> ListNonempty a -> a

Equivalent to List.Extra.foldr1

fromPair 1 [ 2, 3 ] |> foldr (+) 0 == 6

filter : (a -> Basics.Bool) -> ListNonempty a -> List a

Similar to List.filter. Returns List because we cannot guarantee any elements will pass the test.

fromPair 1 [ 2, 3, 4 ] |> filter (\n -> n > 2) == [ 3, 4 ]

fromPair 1 [ 2, 3, 4 ] |> filter (\n -> n > 20) == []

filterMap : (a -> Maybe b) -> ListNonempty a -> List b

Similar to List.filterMap. Also returns List.

fromPair "3.5" [ "cat", "4", "ball" ]
    |> filterMap String.toFloat
    == [ 3.5, 4 ]

Utilities

length : ListNonempty a -> Basics.Int

Same as List.length

fromPair 0 [ 1, 2, 3 ] |> length == 4

isSingleton : ListNonempty a -> Basics.Bool

Whether a non-empty list has only a single element

fromPair 0 [ 1, 2, 3 ] |> isSingleton == False

fromPair 0 [] |> isSingleton == True

reverse : ListNonempty a -> ListNonempty a

Same as List.reverse.

fromPair 0 [ 1, 2, 3 ]
    |> reverse
    |> toList
    == [ 3, 2, 1, 0 ]

member : a -> ListNonempty a -> Basics.Bool

Same as List.member

fromPair 0 [ 1, 2, 3 ] |> member 2 == True

fromPair 0 [ 1, 2, 3 ] |> member 5 == False

all : (a -> Basics.Bool) -> ListNonempty a -> Basics.Bool

Same as List.all

fromPair 0 [ 1, 2, 3 ] |> all (\n -> n < 2) == False

fromPair 0 [ 1, 2, 3 ] |> all (\n -> n < 5) == True

any : (a -> Basics.Bool) -> ListNonempty a -> Basics.Bool

Same as List.any

fromPair 0 [ 1, 2, 3 ] |> any (\n -> n > 2) == True

fromPair 0 [ 1, 2, 3 ] |> any (\n -> n > 5) == False

maximum : ListNonempty comparable -> comparable

Similar to List.maximum, but doesn't need to return a Maybe type

 fromPair 0 [1, 2, 3] |> maximum == 3

 fromPair 2 [] |> maximum == 2

minimum : ListNonempty comparable -> comparable

Similar to List.minimum, but doesn't need to return a Maybe type

 fromPair 0 [1, 2, 3] |> minimum == 0

 fromPair 2 [] |> minimum == 2

sum : ListNonempty number -> number

Equivalent to List.sum

fromPair 1 [ 2, 3 ] |> sum == 6

product : ListNonempty number -> number

Equivalent to List.product

fromPair 1 [ 2, 3 ] |> product == 6

Combine

append : ListNonempty a -> ListNonempty a -> ListNonempty a

Similar to List.append.

append (fromPair 0 [ 1, 2 ]) (fromPair 3 [ 4, 5 ])
    |> toList
    == [ 0, 1, 2, 3, 4, 5 ]

concat : ListNonempty (ListNonempty a) -> ListNonempty a

Similar to List.concat

fromPair (fromPair 0 [ 1 ]) [ fromPair 2 [ 3 ] ]
    |> concat
    |> toList
    == [ 0, 1, 2, 3 ]

fromPair (fromPair 0 []) []
    |> concat
    |> toList
    == [ 0 ]

concatMap : (a -> ListNonempty b) -> ListNonempty a -> ListNonempty b

Similar to List.concatMap

concatMap (\n -> fromPair n [ n ]) (fromPair 0 [ 1, 2 ])
    |> toList
    == [ 0, 0, 1, 1, 2, 2 ]

map2 : (a -> b -> result) -> ListNonempty a -> ListNonempty b -> ListNonempty result

Similar to List.map2

map2 (\a b -> a ++ "-" ++ b)
    (fromPair "a" [ "b", "c" ])
    (fromPair "1" [ "2", "3" ])
    |> toList
    == [ "a-1", "b-2", "c-3" ]

map3 : (a -> b -> c -> result) -> ListNonempty a -> ListNonempty b -> ListNonempty c -> ListNonempty result

Similar to List.map3

map3 (\a b c -> ( a, b, c ))
    (fromPair 0 [ 1 ])
    (fromPair 2 [ 3 ])
    (fromPair 4 [ 5 ])
    |> toList
    == [ ( 0, 2, 4 ), ( 1, 3, 5 ) ]

map4 : (a -> b -> c -> d -> result) -> ListNonempty a -> ListNonempty b -> ListNonempty c -> ListNonempty d -> ListNonempty result

Similar to List.map4

map3 (\a b c -> ( a, b, c ))
    (fromPair 0 [ 1 ])
    (fromPair 2 [ 3 ])
    (fromPair 4 [ 5 ])
    |> toList
    == [ ( 0, 2, 4 ), ( 1, 3, 5 ) ]

map5 : (a -> b -> c -> d -> e -> result) -> ListNonempty a -> ListNonempty b -> ListNonempty c -> ListNonempty d -> ListNonempty e -> ListNonempty result

Similar to List.map5

map3 (\a b c -> ( a, b, c ))
    (fromPair 0 [ 1 ])
    (fromPair 2 [ 3 ])
    (fromPair 4 [ 5 ])
    |> toList
    == [ ( 0, 2, 4 ), ( 1, 3, 5 ) ]

Sort

sort : ListNonempty comparable -> ListNonempty comparable

Similar to List.sort

fromPair 1 [ 3, 5, 0, 2, 4 ]
    |> sort
    |> toList
    == [ 0, 1, 2, 3, 4, 5 ]

sortBy : (a -> comparable) -> ListNonempty a -> ListNonempty a

Similar to List.sortBy

fromPair { x = 1, y = 1 } [ { x = 0, y = 2 }, { x = 2, y = 0 } ]
    |> sortBy .x
    |> toList
    == [ { x = 0, y = 2 }, { x = 1, y = 1 }, { x = 2, y = 0 } ]

fromPair { x = 1, y = 1 } [ { x = 0, y = 2 }, { x = 2, y = 0 } ]
    |> sortBy .y
    |> toList
    == [ { x = 2, y = 0 }, { x = 1, y = 1 }, { x = 0, y = 2 } ]

sortWith : (a -> a -> Basics.Order) -> ListNonempty a -> ListNonempty a

Similar to List.sortWith

fromPair 0 [ 1, 2, 3, 4 ]
    |> sortWith (\a b -> compare b a)
    |> toList
    == [ 4, 3, 2, 1, 0 ]

Deconstruct

head : ListNonempty a -> a

Return the first element. Unlike List.head, doesn't need to return a Maybe.

fromPair 0 [ 1, 2, 3 ] |> head == 0

tail : ListNonempty a -> List a

Return everything except the first element. Unlike List.tail, doesn't need to return a Maybe.

fromPair 0 [ 1, 2, 3 ] |> tail == [ 1, 2, 3 ]

rest : ListNonempty a -> List a

Return everything except the last element. Doesn't need to return a Maybe.

fromPair 0 [ 1, 2, 3 ] |> rest == [ 0, 1, 2 ]

last : ListNonempty a -> a

Return the last element. Doesn't need to return a Maybe.

fromPair 0 [ 1, 2, 3 ] |> head == 3

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

Equivalent to (\elems -> (head elems, tail elems))

fromPair 0 [ 1, 2, 3 ] |> uncons == ( 0, [ 1, 2, 3 ] )

unconsLast : ListNonempty a -> ( List a, a )

Equivalent to (\elems -> (rest elems, last elems))

fromPair 0 [ 1, 2, 3 ] |> unconsLast == ( [ 0, 1, 2 ], 3 )

take : Basics.Int -> ListNonempty a -> ListNonempty a

Return the first N elements. Always includes the first element, regardless of the value of N. If this behavior is undesired, use toList and List.take

fromPair 0 [ 1, 2, 3 ] |> take 2 |> toList == [ 0, 1 ]

fromPair 0 [ 1, 2, 3 ] |> take 0 |> toList == [ 0 ]

drop : Basics.Int -> ListNonempty a -> ListNonempty a

Return all elements except for the first N elements. Always includes the last element, regardless of the value of N. If this behavior is undesired, use toList and List.drop

fromPair 0 [ 1, 2, 3 ] |> drop 2 |> toList == [ 2, 3 ]

fromPair 0 [ 1, 2, 3 ] |> drop 10 |> toList == [ 3 ]

takeLast : Basics.Int -> ListNonempty a -> ListNonempty a

Return the last N elements. Always includes the last element, regardless of the value of N. If this behavior is undesired, use toList >> List.reverse >> List.take n >> List.reverse

fromPair 0 [ 1, 2, 3 ] |> takeLast 2 |> toList == [ 2, 3 ]

fromPair 0 [ 1, 2, 3 ] |> takeLast 0 |> toList == [ 3 ]

dropLast : Basics.Int -> ListNonempty a -> ListNonempty a

Return all elements except for the last N elements. Always includes the first element, regardless of the value of N. If this behavior is undesired, use toList >> List.reverse >> List.drop n >> List.reverse

fromPair 0 [ 1, 2, 3 ] |> dropLast 2 |> toList == [ 2, 3 ]

fromPair 0 [ 1, 2, 3 ] |> dropLast 10 |> toList == [ 3 ]

unzip2 : ListNonempty ( a, b ) -> ( ListNonempty a, ListNonempty b )

Similar to List.unzip.

fromPair ( "a", 1 ) [ ( "b", 2 ), ( "c", 3 ) ]
    |> unzip2
    == ( fromPair "a" [ "b", "c" ]
       , fromPair 1 [ 2, 3 ]
       )

unzip3 : ListNonempty ( a, b, c ) -> ( ListNonempty a, ListNonempty b, ListNonempty c )

Similar to unzip2, but with 3-tuples.

fromPair ( 1, 2, 3 ) [ ( 4, 5, 6 ), ( 7, 8, 9 ) ]
    |> unzip3
    == ( fromPair 1 [ 4, 7 ]
       , fromPair 2 [ 5, 8 ]
       , fromPair 3 [ 6, 9 ]
       )