Skip to content

Instantly share code, notes, and snippets.

@Microtribute
Forked from theburningmonk/elm_extend_records.elm
Created February 14, 2021 01:32
Show Gist options
  • Save Microtribute/92861ceaa3c17e1d18325ef52cecb553 to your computer and use it in GitHub Desktop.
Save Microtribute/92861ceaa3c17e1d18325ef52cecb553 to your computer and use it in GitHub Desktop.
Extending Elm records
-- Extensible Records
-- given a record
x = { age = 42, name = "Boke" }
-- you can clone and remove a field in the process
{ x - age } -- { name = "Boke" }
-- you can also add a field
{ x | species = "Jade Dragon" } -- { age = 42, name = "Boke", species = "Jade Dragon" }
-- you can mix them up
{ x - age | species = "Jade Dragon" } -- { name = "Boke", species = "Jade Dragon" }
-- Composible Record Types
-- given these type aliases for extensible records
type Named a = { a | name : String }
type Aged a = { a | age : Int }
type Species a = { a | species : String }
-- them can be composed together
boke : Named(Aged(Species {}))
boke = { name = "Boke", age = 42, species = "Jade Dragon" }
-- same goes to functions
aboutMe : Named(Aged(Species {})) -> String
aboutMe { age, name, species } = name ++ " is a " ++ species ++ " at " ++ (show age) ++ " years of age"
aboutMe boke -- Boke is a Jade Dragon at 42 years of age
-- type aliases defined using this syntax can still be composed as the inner most part
type NPC = { name : String, age : int }
spyrion : Species(NPC)
spyrion = { name = "Spyrion", age = 42, species = "Ruby Dragon" }
-- similarly you can just defined bespoke labels too
shady : Named(Species { age : Int })
shady = { name = "Shady", age = 21, species = "Goblin" }
-- Structural Typing
-- this function can take any record that has a name field
whoAmI { name } = "My name is " ++ name
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment