Go right to the Examples Page and work through each of the examples, one by one. They actually have useful comments.
Then go visit the Docs Page and visit most of the articles (in order). The important ones are the Quick Start for JavaScript Programmers, the Syntax Reference. Browse the entire Elm Language Guide.
Also of interest is the cool Elm Cheat Sheet.
Now, here’s one version of Hello, World:
import Html exposing (text) main = text "Hello World"
You can run this in the Try Elm playground. (There are other playgrounds out there, too, including Ellie and runelm.io.) To make your own app on your own machine, store the program in the file hello.elm and use the command line:
$ elm make hello.elm
If you’re running Elm for the first time in this directory, Elm will realize you haven’t set anything up, so it will ask you for permission to install three packages (elmlang/core, elmlang/html, and elmlang/virtualdom). The installation will write information about the packages into the file elmpackage.json and will download the packages themselves from a global repository and place them in the folder elmstuff.
After the packages are installed, the elm make
command continues by producing the output file index.html. Go ahead and run this however you normally “run” (or view) HTML pages (e.g., open index.html
on macOS, or start index.html
on Windows, or just drag it into a browser).
Here’s another example:
import Html exposing (Html, ul, li, text) import List exposing (reverse, map, repeat) fibsUpTo : Int > List Int fibsUpTo n = let accumulate fibs = case fibs of x :: y :: rest > if x + y > n then fibs else accumulate (x+y::fibs) _ > [] in reverse (accumulate [1, 0]) main : Html Never main = fibsUpTo 100000 > map (toString >> text >> repeat 1 >> li []) > ul []
You can run this in an online Elm runner, or on your local machine. Here’s an easy way to build and run in one step locally (on macOS):
$ elm make fib.elm && open index.html
Do you see what’s going on? The Elm expression
ul [] [ li [] [text 0] , li [] [text 1] , li [] [text 1] , li [] [text 2] , ... , li [] [text 75025] ]
evaluates to the HTML:
<ul><li>0</li><li>1</li><li>1</li><li>2</li>...<li>75025</li></ul>
So ul
is a function which takes a list of HTML attributes (yes it was empty in this example), and a list of (child) HTML elements, and produces an HTML unordered list element.
You may have been wondering....
Are those type annotations necessary?
No, Elm can figure out types for you. But the annotations add some nice documentation, and most Elm programmers use them.
What is the typeHtml Never
thatmain
has?
It is the type of HTML elements that generate messages of typeNever
.
Why are Elm type annotations on a separate line, and not interleaved into the function definition?
It’s so they are unobtrusive. And so you can add them later to code that doesn’t have them, with less chance of messing things up.
How about some graphics? Just like Elm has functions for HTML elements and attributes, it has functions for the elements and attribites of SVG also. Here’s a little app that makes a pretty picture:
import Html exposing (Html) import Svg exposing (..) import Svg.Attributes exposing (..) main : Html Never main = svg [ width "300", height "300", viewBox "150 150 300 300" ] (List.map shape (List.range 0 23)) shape : Int > Svg Never shape n = let angle = 15 * toFloat n > degrees in circle [ cx (100 * cos angle > toString) , cy (100 * sin angle > toString) , r "15" , fill < "hsl(" ++ (15 * n > toString) ++ ", 90%, 60%)" ] []
If you try to compile this with elm make colored_circles.elm
now, you’ll get an error because Elm cannot find the Svg
module by default. That module exists in the package elmlang/svg. So first enter:
$ elm package install elmlang/svg
Now you can compile and open (on a Mac) with:
$ elm make colored_circles.elm && open index.html
Pssst, this code works in an online editor, too.
We’ll begin our techincal introduction to Elm with its type system. Elm is statically typed. This means you can tell the type of every expression in your program without ever running it.
The five simple types are Bool
, Int
, Float
, Char
, and String
. Type names start with an uppercase letter.
$ elm repl > 7.5 * 3.88 29.099999999999998 : Float > False && True False : Bool > 7 / 2 3.5 : Float > 7 // 2 3 : Int > 7 % 2 1 : Int > 'π' 'π' : Char > "Привет мир" "Привет мир" : String > String.length("Привет мир") 10 : Int
Elm has lists. Good to know: List String
and List Float
are different types.
> ["spot", "spike"] ["spot","spike"] : List String > [1.5, 2.2, sqrt(110)] [1.5,2.2,10.488088481701515] : List Float > [[], ['c'], ['c','a','t']] [[],['c'],['c','a','t']] : List (List Char) > 'd' :: ['o', 'g'] ['d','o','g'] : List Char > False :: True :: False :: [] [False,True,False] : List Bool
Elm’s product types are called tuples:
> (10//2, "dog", False) (5,"dog",False) : ( Int, String, Bool ) > ('$', 'π') ('$','π') : ( Char, Char ) > () () : ()
That last type is the type of zeroelement tuples. You can make tagged prodcuts, called records:
> p = {x=5.0, y=3.2, color="red"} { x = 5, y = 3.2, color = "red" } : { color : String, x : Float, y : Float } > p.x 5 : Float > .x p 5 : Float > {p  color="green"} { x = 5, y = 3.2, color = "green" } : { x : Float, y : Float, color : String }
Elm handles sum types through its custom types. Use pattern matching to get at the variants:
> type Shape = Circle Float  Rectangle Float Float > area s =\  case s of\  Circle r > pi * r * r\  Rectangle w h > w * h: Repl.Shape > Float > > area (Circle 10) 314.1592653589793 : Float > area (Rectangle 7 6) 42 : Float
Those backslashes are not part of Elm. I just had to type them because that is the way you tell the REPL that your entry continues on the next line. And those vertical bar symbols are the prompt you get when you are continuing an entry across multiple lines.
This type declaration created a new type called Shape
, a function Circle
that takes in a float and produces a shape, and a function Rectangle
that (essentially) takes in two floats and produces a shape. You can call Circle
and Rectangle
constructors if you like, but don’t call them types.
Functions are values so they have types too:
> \n > n // 2 <function> : Int > Int > \(x, y) > 2 * x % y <function> : ( Int, Int ) > Int > \a > \b > "hello" :: b :: a <function> : List String > String > List String > Circle <function> : Float > Repl.Shape > Rectangle <function> : Float > Float > Repl.Shape
You can infer that the type of \x > [x*pi, 2*x*pi]
is Float > List Float
.
But what is the type of \x > [x]
? Interesting question. Certainly, the type of the result of calling this function is pretty obvious:
> (\x > [x]) "dog" ["dog"] : List String > (\x > [x]) False [False] : List Bool
So it looks like the argument of the function can be of any type, and the result is a list of whatever the argument type is. Is that so?
> \x > [x] <function> : a > List a
Yep it is. And as you might have guessed, type variables start with a lower case letter. Here are some more examples:
> \x > (x, x) <function> : a > ( a, a ) > \x > \y > (x, (y, x), y) <function> : a > b > ( a, ( b, a ), b ) > \x > \y > \(z, w) > y / 3 <function> : a > Float > ( b, c ) > Float > type Tree a = Leaf a  Node (Tree a) (Tree a) > Node (Leaf 3) (Node (Leaf 5) (Leaf 8)) Node (Leaf 3) (Node (Leaf 5) (Leaf 8)) : Tree number > [] [] : List a
That tree datatype was pretty cool, wasn’t it? It is really common to see type variables in custom types. In fact, one of the most common such types in Elm is the Maybe
type, which Elm uses because it doesn’t have exceptions or null references:
type Maybe a = Just a  Nothing
Maybes are used a lot:
> import List exposing(head, tail, minimum, maximum) > head [1,2,3] == Just 1 True : Bool > head [] == Nothing True : Bool > tail [1,2,3] == Just [2,3] True : Bool > tail [] == Nothing True : Bool > List.maximum [6, 9, 4, 20, 1] == Just 20 True : Bool > List.maximum [] == Nothing True : Bool > maximum [6, 9, 4, 20, 1] == Just 20 True : Bool > maximum [] == Nothing True : Bool
Generally, a type variable can be instantiated with (or unified with) any concrete type whatsoever. That is, a function that takes a List a
as its parameter can be called with a List Float
argument. No problem. But sometimes not just any type will do:
\x > \y > x + y
makes sense only for Ints or Floats
\x > \y > x < y
makes sense only for Ints, Floats, Chars, Strings, and certain others
\x > \y > x ++ y
makes sense only for Lists or Strings
So how to we infer these types? if we have to give a type to \x > \y > x ++ y
we CANNOT say:
a > a > a
, because that allows too many types for a
String > String > String
, because that would exclude lists
List a > List a > List a
, because that would exclude strings
Elm’s answer is to introduce special type variables:
appendable
, which can be instantiated only with the type String
or any type with the form List a
.
number
, which can be instantiated only with Int
or Float
comparable
, which can be instantiated only with numbers, characters, strings, lists of comparable things, and tuples of comparable things with 6 or less elements.
If you are coming to Elm from Haskellland, you might think thatnumber
,comparable
, andappendable
are type classes. Well they are not. They are simply type variables that the compiler has intimate knowledge of and are treated very special. They are a far weaker concept than type classes. Elm does not have type classes. You cannot create your own special type variables.
Also, you might run into the type variablecompappend
which either is or is not one of these special variables: even the official Elm FAQ seems conflicted on this question. Sigh.
\(x, y) > (x+1, y+1)
? (Use the REPL)
At the language level, Elm programs are made up of modules. Each module can export only certain things and import certain things. If you don’t start your file with a module
declaration, a module named Main
is assumed. Learn by example. Here is a module that contains three values (all functions) but exports only one of them:
module Anagrams exposing (anagrams) import String exposing (toList, fromList) import List exposing (concatMap, map, foldr) insertEverywhere : a > List a > List (List a) insertEverywhere x xs = case xs of [] > [[x]] (y::ys) > (x::y::ys) :: map ((::)y) (insertEverywhere x ys) permutations : List a > List (List a) permutations = foldr (concatMap << insertEverywhere) [[]] anagrams : String > List String anagrams s = s > toList > permutations > map fromList
And here is an app that uses the module:
import Anagrams exposing (anagrams) import Html exposing (Html, pre, text) main = pre [] [anagrams "aeginrst" > String.join "\n" > text]
WHat do you have to explicitly import? Good question. There are a few imports that are implicitly done for you at the top of every Elm file. These imports as of Elm 0.18 are:
import Basics exposing (..) import List exposing ( List, (::) ) import Maybe exposing ( Maybe( Just, Nothing ) ) import Result exposing ( Result( Ok, Err ) ) import String import Tuple import Debug import Platform exposing ( Program ) import Platform.Cmd exposing ( Cmd, (!) ) import Platform.Sub exposing ( Sub )
In addition to the modules you write yourself, there are hundreds and hundreds of standard modules and communitycontributed modules stored in a global package repository. (Just FYI, the modules in the default import list, come from a very important package called elmlang/core
.) You grab these modules via the Elm package manager, which we’ll cover pretty soon. But first, more about Elm itself.
Elm predefines the following infix operators:
Operators  Prec  Assoc  Description 

<<  9  R  composition: (f << g)x == f(g(x))

>>  9  L  composition: (f >> g)x == g(f(x))

^  8  R  exponentiation 
* / // % rem  7  L  multiply, divide, integer divide, modulo, remainder 
+   6  L  add, subtract 
:: ++  5  L  cons, append 
< <= > >= == /=  4  None  less, less or equal, greater, greater or equal, equal, not equal 
&&  3  R  shortcircuit logical and 
  2  R  shortcircuit logical or 
<  0  R  application: f < x == f(x)

>  0  L  application: f > x == f(x)

To use an infix operator in the prefix position, enclose it in parentheses:
> (*) 3 7 21 : number > times3 = (*) 3 <function> : number > number > times3 50 150 : number
You can create your own infix operators, too. Set the precedence and associativity with the infixl
(left associative), infixr
(right associative) or infix
(nonassociative) functions. Example:
import Html exposing (div, text) (<*>) x y = 2 * x + y infixr 7 <*> main = div [] [text < toString < 8 <*> 2 ^ 3 <*> 5 + 2]
The above script produces the value 39. We made the new operator right associative and placed its precedence lower than expoentation but higher than addition. The evaluation proceeds like so:
8 <*> 2 ^ 3 <*> 5 + 2 = 8 <*> 8 <*> 5 + 2 = 8 <*> 21 + 2 = 37 + 2 = 39
Elm’s let
expression lets you bind local variables to compose a more complex expression. Example:
let x = 3 * 8 y = 4 ^ 2 in 2 * x + y
It’s pretty much shorthand for:
(\x > \y > 2 * x + y)(3 * 8)(4 ^ 2)
Elm wants to be a pure functional language. This means: Every function should return the same value for the same arguments no matter when it is called. So there shouldn't be any global state. There should be no side effects, no mutable variables, no assignments, no loops.
Hold on! Why would we ever care about this? Well, it turns out that pure functions have lots of advantages:
 They are easier to reason about and prove correct
 They are easier to to compose
 They are easier to to test
 They are easier to to debug
 They are easier to to parallelize
Okay, now that we know pure functions are good, how do we program in such a way? You might have to change your thinking:
Avoid  Alternative 

While loops  Tail recursion 
For loops through sequences  Map, filter, reduce, or other functions on lists 
For loops over numbers  Functions on ranges, or tail recursion 
Adding elements to a data structure  Return a new data structure, just like the old one, except with a new element 
Modifying a data structure  Return a new data structure, just like the old one, except with the modification made 
Modifying the DOM  The DOM is just a data structure, so see above, and use a Virtual DOM that backs the real DOM 
Throwing exceptions or setting global error codes  Chain maybes and results 
Asking for a random number, the current time, or the current position of the mouse  Don’t ask for these things! We cannot make pure functions that return these! But the callbacks for these things can be pure 
We’ll look at the basics first. Then we’ll get into the interactive “effects” after that.
Here’s a typical solution using a while loop that determines how many years you need to grow $1000 into $2000 at a 3.5% annual interest rate:
years = 0 amount = 1000 while amount < 2000: amount = amount * 1.035; years = years + 1 return years
Elm doesn’t have assignable, mutable variables, so we have to create a function that takes us from one (years, amount)
pair to the next one. Here’s the progression we need to capture in a function:
yearsNeeded(0, 1000) = yearsNeeded(1, 1035.0) = yearsNeeded(2, 1071.225) = yearsNeeded(3, 1108.7178749999998) = yearsNeeded(4, 1147.5230006249997) = yearsNeeded(5, 1187.6863056468746) = yearsNeeded(6, 1229.2553263445152) = yearsNeeded(7, 1272.279262766573) = yearsNeeded(8, 1316.809036963403) = yearsNeeded(9, 1362.897353257122) = yearsNeeded(10, 1410.598760621121) = yearsNeeded(11, 1459.9697172428603) = yearsNeeded(12, 1511.0686573463602) = yearsNeeded(13, 1563.9560603534826) = yearsNeeded(14, 1618.6945224658543) = yearsNeeded(15, 1675.348830752159) = yearsNeeded(16, 1733.9860398284845) = yearsNeeded(17, 1794.6755512224813) = yearsNeeded(18, 1857.489195515268) = yearsNeeded(19, 1922.5013173583022) = yearsNeeded(20, 1989.7888634658427) = yearsNeeded(21, 2059.431473687147) = 21
We want a function (years, amount)
and make a recursive call with (years + 1, amount * 1.035)
. But if amount
is already over 2000, we have our answer and return years
.
 Here's the function yearsNeeded years amount = if amount > 2000 then years else yearsNeeded (years + 1) (amount * 1.035)  Call it to solve our initial problem yearsNeeded 0 1000
Another example. How many steps are there in the Collatz Sequence for a given number?
def collatz(n): count = 0 while n > 1: n = even(n) ? n / 2 : 3 * n + 1 count = count + 1 return count
Our first inclination might be to simply write
 Inefficient collatz n = if n == 1 then 0 else collatz(if n % 2 == 0 then n // 2 else 3 * n + 1) + 1
but this is inefficient because it is not tailrecursive. Instead, let’s use the technique from the previous example:
collatz n = let c count n = if n == 1 then count else c (count+1) (if n % 2 == 0 then n // 2 else 3 * n + 1) in c 0 n
while
loops, you also replace for
loops with this technique. First give a program in C that runs through all the integers in the range 0 to 300 (inclusive) and sums up those and only those values evenly divisible by 3 or 7. Then, write the same program in Elm, using tail recursion.
Most forloops over lists iterate over each list item or each list index (or both).
So how do we do functional programming on the web? Surely interaction requires state? Right?
Here’s how Elm does it. Up to now, we’ve only seen examples where main
has the type Html.Html a
. But it can also have the type Platform.Program a b c
. The easiest ways to make objects of type Program a b c
are with the functions Html.beginnerProgram
and Html.program
. Here’s a “beginner program” the computes a BMI from two text fields, as you type:
import Html exposing (Html, body, input, text, h1, p) import Html.Attributes exposing (style, value) import Html.Events exposing (onInput) type alias Model = { weight: String, height: String } type Msg = ChangeWeight String  ChangeHeight String bmi pounds inches = let kilosPerPound = 0.453592 metersPerInch = 0.0254 kilos = pounds * kilosPerPound meters = inches * metersPerInch in kilos / (meters * meters) bmiMessage weightString heightString = case (String.toFloat weightString, String.toFloat heightString) of (Ok w, Ok h) > "The BMI is " ++ toString (bmi w h) (Err s, _) > s (_, Err s) > s main = Html.beginnerProgram { model = model, view = view, update = update } model : Model model = { weight = "0", height = "0"} update : Msg > Model > Model update msg model = case msg of ChangeWeight w > { model  weight = w } ChangeHeight h > { model  height = h } view : Model > Html Msg view model = body [style [("textAlign", "center")]] [ h1 [] [text "Find Your BMI"] , p [] [text "Weight in pounds ", input [onInput ChangeWeight, value model.weight] []] , p [] [text "Height in inches ", input [onInput ChangeHeight, value model.height] []] , p [] [text < bmiMessage model.weight model.height] ]
The beginnerProgram
function creates a program out of three parts:
All the functions in the code are pure. They just get called at times you can’t predict.
beginnerProgram
to program
. Read about subscriptions in the Elm Tutorial and the Elm Guide.
Elm programs are made up of modules. Where can you find modules? Thousands of these have been bundled up into pacakges which you can install with the Elm package manager. There are many hundreds of packages out there. Here are few of them:
Package  Modules 

elmlang/core  Array Basics Bitwise Char Color Date Debug Dict Json.Decode Json.Encode List Maybe Platform Platform.Cmd Platform.Sub Process Random Regex Result Set String Task Time Tuple 
elmlang/virtualdom  VirtualDom 
elmlang/html  Html Html.Attributes Html.Events Html.Keyed Html.Lazy 
elmlang/svg  Svg Svg.Attributes Svg.Events Svg.Keyed Svg.Lazy 
elmlang/http  Http Http.Progress 
elmlang/websocket  WebSocket WebSocket.LowLevel 
elmcommunity/basicsextra  Basics.Extra 
elmcommunity/webgl  WebGL WebGL.Settings WebGL.Settings.Blend WebGL.Settings.DepthTest WebGL.Settings.StencilTest WebGL.Texture 
elmcommunity/elmtest  Expect Fuzz Test Test.Runner 
elmcommunity/linearalgebra  Math.Matrix4 Math.Vector2 Math.Vector3 Math.Vector4 
mgold/elmdateformat  Date.Format Date.Local Time.Format 
Make sure to browse the entire package repository.
Finally, just for fun, here are partial contents of some of the more popular modules:
(==): a > a > Bool  equality, may give runtime error (/=): a > a > Bool  inequality, may give runtime error (<): comparable > comparable > Bool (>): comparable > comparable > Bool (<=): comparable > comparable > Bool (>=): comparable > comparable > Bool (<): comparable > comparable > Bool max: comparable > comparable > Bool min: comparable > comparable > Bool type Order = LT  EQ  GT compare: comparable > comparable > Order not: Bool > Bool > Bool (&&): Bool > Bool > Bool  logical and (short circuit) (): Bool > Bool > Bool  logical or (short circuit) xor: Bool > Bool > Bool (+): number > number > number (): number > number > number (*): number > number > number (/): Float > Float > Float  division (promotes Int args to Float) (^): number > number > number  exponentiation (//): Int > Int > Int  integer division (rem): Int > Int > Int  remainder (%): Int > Int > Int  modulo negate: number > number abs: number > number sqrt: Float > Float clamp: number > number > number > number  low hi value logBase : Float > Float > Float  base value e : Float pi : Float cos : Float > Float sin : Float > Float tan : Float > Float acos : Float > Float asin : Float > Float atan : Float > Float  don't use this atan2 : Float > Float > Float  y x round : Float > Int floor : Float > Int ceiling : Float > Int truncate : Float > Int  round toward zero toFloat : Int > Float degrees : Float > Float radians : Float > Float turns : Float > Float toPolar : (Float, Float) > (Float, Float) fromPolar : (Float, Float) > (Float, Float) isNaN : Float > Bool isInfinite : Float > Bool toString : a > String (++) : appendable > appendable > appendable identity : a > a always : a > b > a (<) : (a > b) > a > b (>) : a > (a > b) > b (<<) : (b > c) > (a > b) > a > c (>>) : (a > b) > (b > c) > a > c flip : (a > b > c) > b > a > c curry : ((a, b) > c) > a > b > c uncurry : (a > b > c) > (a, b) > c type Never  the type with no values never : Never > a
Strings are enclosed in double quotes and are not lists of characters.
isEmpty: String > Bool length: String > Int reverse: String > String repeat: Int > String > String cons: Char > String > String uncons: String > Maybe (Char, String) fromChar: Char > String append: String > String > String concat: List String > String split: String > String > List String  sep, stringToSplit join: String > List String > String  sep, stringToJoin words: String > List String lines: String > List String slice: Int > Int > String > String  start, end, stringToSlice left: Int > String > String right: Int > String > String dropLeft: Int > String > String dropRight: Int > String > String contains: String > String > Bool startsWith: String > String > Bool  sub, largerString endsWith: String > String > Bool  sub, largerString indexes: String > String > List Int indices: String > String > List Int toInt: String > Result String Int toFloat: String > Result String Float toList: String > List Char fromList: List Char > String toUpper: String > String toLower: String > String pad: Int > Char > String > String  len, padChar, stringToPad padLeft: Int > Char > String > String  len, padChar, stringToPad padRight: Int > Char > String > String  len, padChar, stringToPad trim: String > String trimLeft: String > String trimRight: String > String map: (Char > Char) > String > String filter: (Char > Bool) > String > String foldl: (Char > b > b) > b > String > b foldr: (Char > b > b) > b > String > b any: (Char > Bool) > String > Bool all: (Char > Bool) > String > Bool
isEmpty : List a > Bool length : List a > Int reverse : List a > List a member : a > List a > Bool head : List a > Maybe a tail : List a > Maybe (List a) filter : (a > Bool) > List a > List a take : Int > List a > List a drop : Int > List a > List a singleton : a > List a repeat : Int > a > List a range : Int > Int > List Int (::) : a > List a > List a append : List a > List a > List a concat : List (List a) > List a intersperse : a > List a > List a partition : (a > Bool) > List a > (List a, List a) unzip : List (a, b) > (List a, List b) map : (a > b) > List a > List b map2 : (a > b > result) > List a > List b > List result map3 : (a > b > c > result) > List a > List b > List c > List result map4 : (a > b > c > d > result) > List a > List b > List c > List d > List result map5 : (a > b > c > d > e > result) > List a > List b > List c > List d > List e > List result filterMap : (a > Maybe b) > List a > List b concatMap : (a > List b) > List a > List b indexedMap : (Int > a > b) > List a > List b foldr : (a > b > b) > b > List a > b foldl : (a > b > b) > b > List a > b sum : List number > number product : List number > number maximum : List comparable > Maybe comparable minimum : List comparable > Maybe comparable all : (a > Bool) > List a > Bool any : (a > Bool) > List a > Bool scanl : (a > b > b) > b > List a > List b sort : List comparable > List comparable sortBy : (a > comparable) > List a > List a sortWith : (a > a > Order) > List a > List a
type Maybe a = Just a  Nothing withDefault : a > Maybe a > a map : (a > b) > Maybe a > Maybe b map2 : (a > b > value) > Maybe a > Maybe b > Maybe value map3 : (a > b > c > value) > Maybe a > Maybe b > Maybe c > Maybe value map4 : (a > b > c > d > value) > Maybe a > Maybe b > Maybe c > Maybe d > Maybe value map5 : (a > b > c > d > e > value) > Maybe a > Maybe b > Maybe c > Maybe d > Maybe e > Maybe value andThen : (a > Maybe b) > Maybe a > Maybe b
type Result error value = Ok value  Err error map : (a > value) > Result x a > Result x value map2 : (a > b > value) > Result x a > Result x b > Result x value map3 : (a > b > c > value) > Result x a > Result x b > Result x c > Result x value map4 : (a > b > c > d > value) > Result x a > Result x b > Result x c > Result x d > Result x value map5 : (a > b > c > d > e > value) > Result x a > Result x b > Result x c > Result x d > Result x e > Result x value andThen : (a > Result x b) > Result x a > Result x b withDefault : a > Result x a > a toMaybe : Result x a > Maybe a fromMaybe : x > Maybe a > Result x a mapError : (x > y) > Result x a > Result y a