DocsStandard library
Collections.
Choose lists, optional values, results, tuples, and dictionaries for everyday data.
Most everyday data fits one of a few shapes. Reach for a list when you have a sequence, Maybe when a value might be missing, and Result when something can succeed or fail. When you need to look things up by key, use a dictionary. All of them are immutable: operations hand back new values and never change their inputs.
API reference: List · Range · Maybe · Result · Tuple · Dict
List.
import List
main() =
numbers = [1, 2, 3, 4]
doubled = List.map { number -> number * 2 } numbers
large = List.filter { number -> number > 4 } doubled
print large
print (List.foldl (+) 0 large)
This prints [6, 8] and 14. map transforms every element, and filter keeps the ones that satisfy a predicate. Both keep the order of the list and call your callback from left to right.
A fold boils a list down to a single value. List.foldl combine initial values calls combine element accumulator from left to right. The element comes first, which matters for operations like subtraction. foldr goes from right to left instead. Any effects your callback performs carry through these functions.
When you only want the effects and don’t need a new list, use List.each. Adding to the front of a list or taking its tail is constant time, while length has to walk the whole list. Updates share tails rather than copying every element.
Range.
When you need the numbers as data, use List.range. When you only need to visit each one, Range.each is lighter:
import Range
main() =
print (List.range 2 4)
Range.each { number -> print (number * number) } 2 4
print (List.range 4 2)
[2, 3, 4]
4
9
16
[]
Both endpoints are included. If the start is greater than the end, nothing is visited, because a range never counts down. Range.each avoids building a list. Both functions work with integer or float bounds, and the bounds should be finite.
Maybe.
import Maybe
import String
main() =
number = String.toInt "42"
print (Maybe.withDefault 0 number)
case String.toInt "hello" of
Nothing -> print "not an integer"
Just value -> print value
The prelude provides Maybe, Nothing and Just, plus qualified access to Maybe.withDefault. Import it with an exposing list to use withDefault unqualified. A default is a good fit when substituting a value really makes sense; when it doesn’t, pattern matching lets the missing case take its own path.
The Maybe API lists its constructors and the fallback function.
Result.
Result error value is either Err error or Ok value. Import its constructors so you can match on them:
import Result exposing (Result(..))
positive number = if number > 0 then Ok number else Err "expected a positive number"
main() =
case positive (-2) of
Ok value -> print value
Err message -> print message
Result.map changes a successful value, and mapError changes the error. andThen chains a step that itself returns a result. These are ordinary data transformations, which is different from raising a failure effect.
The Result API documents each transformation along with its checked signature.
Tuple.
A pair or triple groups a few values without you having to declare a type. Take it apart when you need the pieces:
import Tuple
main() =
entry = ("Ada", 4)
(name, count) = entry
print "#{name}: #{count}"
print (Tuple.swap entry)
Ada: 4
(4, "Ada")
Tuple.first and Tuple.second pick one part of a pair. Tuples are best for a small, local result. Once callers would have to remember what each position means, a record with named fields is the kinder choice.
Dict.
import Dict
main() =
scores = Dict.fromList [("Ada", 3), ("Lin", 5)]
updated = Dict.insert "Ada" 4 scores
print (Dict.get "Ada" updated)
print (Dict.keys updated)
This prints Just 4 and ["Ada", "Lin"]. Keys need an Ord instance. get returns a Maybe because the key might not be there. Inserting or removing leaves the other entries alone, and the original dictionary is still usable.
Traversals visit entries in ascending key order, except foldr, which goes in descending order. Dictionary callbacks receive a (key, value) pair. update calls its callback once: returning Nothing removes the key, and Just value stores a value.
Lookups and single updates take logarithmic time, size is constant, and listing or mapping every entry is linear. If fromList sees the same key twice, the later value wins.
Look up an API.
The API reference is generated from the source documentation. These guides explain when to use each structure, and the API entries give the checked signatures and the details of each declaration.
