I want a thing (person, object, whatever) to have abilities (jump, run, etc.). I want some things to only have certain abilities. These are my current types:
type Ability =
| Jump
| Stay
| Run
| Walk
type Person = {
abilities : Ability Set // OK, since a person should be able to do all of the above
}
type InanimateObject = {
abilities : Ability Set // Not OK, it should only be able to "Stay"
}
type ThingWithAbilities =
| Person of Person
| InanimateObject of InanimateObject
I want a caller of my API to be able to ask for a ThingWithAbilities
with a specific ability. Example: Give me all objects of ThingWithAbilities
that has the ability "Jump". How can I model this in a good way? I want to make it impossible to create an InanimateObject
with the ability "jump" in the code.
If you want to do this in a type-safe way, then you'll need to define different types for different sets of abilities:
type InanimateAbility =
| Stay
type AnimateAbility =
| Jump
| Run
| Walk
type Ability =
| Inanimate of InanimateAbility
| Animate of AnimateAbility
type Person = {
abilities : Ability Set
}
type InanimateObject = {
abilities : InanimateAbility Set
}
Here, InanimateAbility
is a type for abilities that only inanimate objects have and AnimateAbility
is a type for abilities that are unique to animate objects. Ability
combines both of these and represents any kind of ability. Person
can then have a set of Abilitiy
values, but you can restrict abilities of InanimateObject
to a set of InanimateAbility
values.
This works fine as long as you do not have too many combinations - if you had four different kinds of objects with various subsets of abilities, then it might get messy. In that case, you would probably just use one type with a runtime check to make sure that you only assign allowed abilities to each object.
you could model them seperately and then define your Person/Object types with reference to the atomic abilities
type Jump = Jump
type Stay = Stay
type Run = Run
type Walk = Walk
type Person = {
abilities : Choice<Jump,Stay,Run,Walk> Set
}
type InanimateObject = {
abilities : Stay Set // actually haveing this as a set is a bit odd...but whatever
}
type ThingWithAbilities =
| Person of Person
| InanimateObject of InanimateObject
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With