Collection of examples on places where Elm is different to Haskell.
Used for helping beginners moving from Haskell to Elm. Non-exhaustive list, only to be used alongside the documentation on the Elm site.
Elm uses a single colon (:)
for type signatures. Double colons (::)
is used for cons.
Example
add :: Int -> Int
becomes
add : Int -> Int
Instead of using the dollar symbol $
elm uses <|
and |>
for application in different directions.
Example:
collage (round board.width) (round board.height) $ map (genRect board) board.pieces
becomes
collage (round board.width) (round board.height) <| List.map (genRect board) board.pieces
--
List.map (genRect board) board.pieces |> collage (round board.width) (round board.height)
Instead of using the (.)
symbol Elm uses <<
and >>
for composition in different directions
Example:
isEvenSquareRoot = isEven . sqrt
becomes
isEvenSquareRoot = sqrt >> isEven
-- or
isEvenSquareRoot = isEven << sqrt
There are no list comprehensions in Elm.
Elm has the package focus for lense-like accessors. Due to a lack of template-haskell like functionality, you must always manually create your own focus
Example:
data Patch = Patch {
_colour :: Colour,
_size :: Double,
_coord :: Coordinate
} deriving (Show, Eq, Ord)
mkLabels[''Patch]
becomes
type alias Patch = {
colour: Colour,
size: Float,
coord: Coordinate
}
colour = create .colour (\f r -> { r | colour = f r.colour })
coord = create .coord (\f r -> { r | coord = f r.coord })
size = create .size (\f r -> { r | size = f r.size })
Elm has no where binding - instead use let
Elm doesn't support multiple body declarations for functions, so instead you have to use case..of
Example:
head [] = error
head (X:xs) = x
becomes
head xs = case xs of
x::xs -> Just x
[] -> Nothing
Functions in Elm as of 0.15.1 have pure type signatures. However, as they are actually implented in JS, it's possible that the underlying code you're calling isn't pure. This gives the effect of Elm the language being pure, but the things it can be used to do can be impure (eg, drawing to screen). Native functions can also produce runtime errors, though there is a drive to rid these from Elm entirely.
Elm has renamed id to identity
Example:
id xs
becomes
identity xs
Elm uses double colons (::)
for cons.
Example
5 : 6 : [7, 8]
becomes
5 :: 6 :: [7, 8]
Instead of throwing errors for empty lists, Elm uses Maybe for head
Example
head [4, 5] == 4
becomes
case head [4, 5] of
Just x -> x == 4
Nothing -> False
Instead of throwing errors for empty lists, Elm uses Maybe for tail
Example
tail [4, 5] == [5]
becomes
case tail [4, 5] of
Just x -> x == [5]
Nothing -> False
Elm has no built-in zip method - instead it provides a map2 function that can be used with the tuple creator (,)
to make a list of size 2 tuples from two lists.
Example:
zip xs ys
becomes
map2 (,) xs ys
Elm renamed show to toString. Confusingly, there is also a method called show in Elm - this generates a HTML element containing a textual representation of the data.
Example:
show [1, 2, 3]
becomes
toString [1, 2, 3]
mod in Elm uses the (%)
symbol.
Example:
isEven x = x `mod` 2 == 0
becomes
isEven x = x % 2 == 0
unwords is replaced by the join function
Example:
unwords $ words "Hello Dave and Jeremy"
becomes
join " " <| words "Hello Dave and Jeremy"
Elm has no cycle built in.
TODO: find documentation for this
The order of the accumalator function arguments are swapped in Elm.
Example:
idx xs = foldl (\x y -> y : x) [] xs
becomes
id xs = List.foldl (\x y -> x :: y) xs []
Elm uses the exposing
keyword to import names into the current namespace.
Example:
import List (map, foldl)
becomes
import List exposing (map, foldl)
TODO: find documentation on elm site for this
Following the module declaration, you must have no identnation level.
Example:
module Coords (pos) where
pos x y = (x, y)
becomes
module Coords exposing (pos)
pos x y = (x, y)