Syntax

``````-- a single line comment

{- a multiline comment
{- can be nested -}
-}
``````

Here's a handy trick that every Elm programmer should know:

``````{--}
add x y = x + y
--}
``````

Just add or remove the `}` on the first line and you'll toggle between commented and uncommented!

### Literals

``````-- Boolean
True  : Bool
False : Bool

42    : number  -- Int or Float depending on usage
3.14  : Float

'a'   : Char
"abc" : String

-- multi-line String
"""
This is useful for holding JSON or other
content that has "quotation marks".
"""
``````

Typical manipulation of literals:

``````True && not (True || False)
(2 + 4) * (4^2 - 9)
"abc" ++ "def"
``````

### Lists

Here are four things that are equivalent:

``````[1..4]
[1,2,3,4]
1 :: [2,3,4]
1 :: 2 :: 3 :: 4 :: []
``````

### Conditionals

``````if powerLevel > 9000 then "OVER 9000" else "meh"
``````

If you need to branch on many different conditions, you just chain this construct together.

``````if key == 40 then n + 1
else if key == 38 then n - 1
else n
``````

You can also have conditional behavior based on the structure of algebraic data types and literals

``````case maybe of
Just xs -> xs
Nothing -> []

case xs of
hd::tl -> Just (hd,tl)
[]     -> Nothing

case n of
0 -> 1
1 -> 1
_ -> fib (n-1) + fib (n-2)
``````

Each pattern is indentation sensitive, meaning that you have to align all of your patterns.

### Union Types

``````type List = Empty | Node Int List
``````

### Records

For more explanation of Elm's record system, see this academic paper.

``````point =                        -- create a record
{ x = 3, y = 4 }

point.x                        -- access field

map .x [point , {x=0 , y=0}]   -- field access function

{ point | x = 6 }              -- update a field

{ point |                      -- update many fields
x = point.x + 1,
y = point.y + 1
}

dist {x , y} = sqrt (x^2 + y^2)                       -- pattern matching on fields

type alias Location = { line : Int , column : Int }   -- type aliases for records

``````

### Functions

``````square n = n^2

hypotenuse a b = sqrt (square a + square b)

distance (a , b) (x , y) = hypotenuse (a - x) (b - y)
``````

Anonymous functions:

``````square = \n -> n^2

squares = List.map (\n -> n^2) [1..100]
``````

### Infix Operators

You can create custom infix operators. Precedence goes from 0 to 9, where 9 is the tightest. The default precedence is 9 and the default associativity is left. You can set this yourself, but you cannot override built-in operators.

``````(?) : Maybe a -> a -> a
(?) maybe default =
Maybe.withDefault default maybe

infixr 9 ?
``````

Use `(<|)` and `(|>)` to reduce parentheses usage. They are aliases for function application.

``````f <| x = f x
x |> f = f x

dot = scale 2 (move (20 , 20) (filled blue (circle 10)))

dot' = circle 10 |> filled blue |> move (20,20) |> scale 2
``````

note: this is borrowed from F#, which borrowed it from Ocaml, which inspired by Unix pipes

Relatedly, `(<<)` and `(>>)` are function composition operators.

The basic arithmetic infix operators all figure out what type they should have automatically.

``````23 + 19    : number
2.0 + 1    : Float

6 * 7      : number
10 * 4.2   : Float

100 // 2  : Int
1 / 2     : Float
``````

There is a special function for creating tuples:

``````(,) 1 2              == (1,2)
(,,,) 1 True 'a' []  == (1,True,'a',[])
``````

You can use as many commas as you want.

### Let Expressions

Let expressions are for assigning variables, kind of like a `var` in JavaScript.

``````let
x = 3 * 8
y = 4 ^ 2
in
x + y
``````

You can define functions and use â€śdestructuring assignmentâ€ť in "let" expressions too.

``````let (x , y) = (3 , 4)
hypotenuse a b = sqrt (a^2 + b^2)
in hypotenuse x y
``````

Let-expressions are indentation sensitive, so each definition must align with the one above it.

### Modules

``````module MyModule exposing (..)

-- qualified imports
import List                    -- List.map, List.foldl
import List as L               -- L.map, L.foldl

-- open imports
import List exposing (..)               -- map, foldl, concat, ...
import List exposing ( map, foldl )     -- map, foldl

import Maybe exposing ( Maybe )         -- Maybe
import Maybe exposing ( Maybe(..) )     -- Maybe, Just, Nothing
import Maybe exposing ( Maybe(Just) )   -- Maybe, Just
``````

Qualified imports are preferred. Module names must match their file name, so module `Parser.Utils` needs to be in file `Parser/Utils.elm`.

### Type Annotations

``````answer : Int

factorial : Int -> Int
factorial n = List.product [1..n]

distance : { x : Float, y : Float } -> Float
distance {x,y} = sqrt (x^2 + y^2)
``````

### Type Aliases

``````type alias Name = String
type alias Age = Int

info : (Name , Age)
info = ("Steve", 28)

type alias Point = { x:Float , y:Float }

origin : Point
origin = { x = 0, y = 0 }
``````