Skip to content

Instantly share code, notes, and snippets.

@padurean
Created March 19, 2016 11:47
Show Gist options
  • Save padurean/60e5d4b942c6ccbe17cc to your computer and use it in GitHub Desktop.
Save padurean/60e5d4b942c6ccbe17cc to your computer and use it in GitHub Desktop.
{-
See Elm docs for more details:
http://elm-lang.org/docs/records#record-types
-}
import Html
import String
origin : { x : Float, y : Float }
origin =
{ x = 0
, y = 0
}
-- You can also define extensible records.
type alias Positioned a =
{ a | x : Float, y : Float }
type alias Named a =
{ a | name : String }
type alias Moving a =
{ a | velocity : Float, angle : Float }
{-
This syntax is defining types that have at least
certain fields, but may have others as well.
So Positioned a is a record with at least an x
and y field.
This means you can define records that have any
subsection of these fields. For example,
-}
lady : Named { age:Int }
lady =
{ name = "Lois Lane"
, age = 31
}
dude : Named (Moving (Positioned {}))
dude =
{ x = 0
, y = 0
, name = "Clark Kent"
, velocity = 42
, angle = degrees 30
}
{-
Then we can make functions that only require
some of those fields:
-}
getName : Named a -> String
getName {name} =
name
names : List String
names =
[ getName dude, getName lady ]
getPos : Positioned a -> (Float,Float)
getPos {x,y} =
(x,y)
positions : List (Float,Float)
positions =
[ getPos origin, getPos dude ]
{-
The getName function works on anything with a name
field, so it can be used on both lady and dude.
Same for getPos which can work on anything with x
and y fields.
So you can write small orthogonal functions that
work with a wide variety of records.
You get much of the freedom of a dynamically typed
language, but the type checker will make sure that
these functions are used safely!
-}
main : Html.Html
main =
Html.text (String.join " " names)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment