Reputation: 2684
Say I have a type in elm (0.18) like this:
type alias CatSimple =
{ color : String
, age : Int
, name : String
, breed : String
}
My project requires that I also have a type that has all the fields of the previous one, but with a few additional fields:
type alias CatComplex =
{ color : String
, age : Int
, name : String
, breed : String
, feral : Bool
, spayed : Bool
}
Now let's say that I need to add another field to CatSimple
. I would have to remember to add it to CatComplex
as well.
I would like to be able to dynamically augment my types so that I can avoid having to update all of them, or having to resort to something like this:
type alias CatComplex =
{ simpleData: CatSimple
, feral : Bool
, spayed : Bool
}
Is there any way to do that in Elm?
If not, does Haskell provide a way to do this?
Upvotes: 2
Views: 165
Reputation: 36385
You can use extensible records in Elm to define a rudimentary sort of field composition:
type alias Cat c =
{ c
| color : String
, age : Int
, name : String
, breed : String
}
type alias FeralCat =
Cat
{ feral : Bool
, spayed : Bool
}
Here's an example of how it could be used:
feralCatSummary : FeralCat -> String
feralCatSummary { color, feral } =
color ++ "; Feral? " ++ toString feral
main : Html msg
main =
text <|
feralCatSummary
{ color = "Blue"
, age = 5
, name = "Billy"
, breed = "Bluecat"
, feral = True
, spayed = False
}
Upvotes: 7
Reputation: 21037
The short answer is no, but there are some things you can do that go in the direction you want:
Have a single type but make the extra info 'optional'
type alias Cat =
{ color : String
, age : Int
, name : String
, breed : String
, feral : Maybe Bool
, spayed : Maybe Bool
}
When you want to pass CatComplex to a function that only uses the Cat fields you could define a Type
type alias CatGeneric a =
{ a|
color : String
, age : Int
, name : String
, breed : String
}
then
fn : CatGeneric a -> Bool
....
and this should type check if you pass either a Cat or a CatComplex
Upvotes: 2