Skip to content

Instantly share code, notes, and snippets.

@theburningmonk
Last active December 24, 2023 17:16
Show Gist options
  • Save theburningmonk/0610b75b24b3b7ca0d1c to your computer and use it in GitHub Desktop.
Save theburningmonk/0610b75b24b3b7ca0d1c 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
@snatvb
Copy link

snatvb commented May 17, 2020

half of what exists here is not working

@noiseOnTheNet
Copy link

Maybe it is not for Elm 0.19

@benkoshy
Copy link

Thanks for the gist.

For future readings, I can say that with Elm .019 you need to explicitly list out all the fields, and cannot append/extend them like the above.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment