如何在 F# 中对受歧视联合的子集进行建模?
How to model a subset of a discriminated union in F#?
我想要一个事物(人,物体,无论什么)有能力(跳跃,运行,等等)。我希望某些东西只具有某些能力。这些是我目前的类型:
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
我希望 API 的来电者能够请求具有特定能力的 ThingWithAbilities
。示例:给我 ThingWithAbilities
中具有 "Jump" 能力的所有对象。我怎样才能很好地建模呢?我想让代码中无法创建具有 "jump" 能力的 InanimateObject
。
如果您想以类型安全的方式执行此操作,则需要为不同的能力集定义不同的类型:
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
}
这里,InanimateAbility
是只有无生命物体才有的能力类型,AnimateAbility
是有生命物体独有的能力类型。 Ability
结合了这两者,代表了任何一种能力。 Person
可以有一组 Abilitiy
值,但是您可以将 InanimateObject
的能力限制为一组 InanimateAbility
值。
只要您没有太多组合,这就可以正常工作 - 如果您有四种不同类型的对象,它们具有不同的能力子集,那么它可能会变得混乱。在这种情况下,您可能只使用一种类型进行运行时检查,以确保您只为每个对象分配允许的能力。
您可以分别对它们建模,然后参考原子能力
定义您的Person/Object类型
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
我想要一个事物(人,物体,无论什么)有能力(跳跃,运行,等等)。我希望某些东西只具有某些能力。这些是我目前的类型:
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
我希望 API 的来电者能够请求具有特定能力的 ThingWithAbilities
。示例:给我 ThingWithAbilities
中具有 "Jump" 能力的所有对象。我怎样才能很好地建模呢?我想让代码中无法创建具有 "jump" 能力的 InanimateObject
。
如果您想以类型安全的方式执行此操作,则需要为不同的能力集定义不同的类型:
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
}
这里,InanimateAbility
是只有无生命物体才有的能力类型,AnimateAbility
是有生命物体独有的能力类型。 Ability
结合了这两者,代表了任何一种能力。 Person
可以有一组 Abilitiy
值,但是您可以将 InanimateObject
的能力限制为一组 InanimateAbility
值。
只要您没有太多组合,这就可以正常工作 - 如果您有四种不同类型的对象,它们具有不同的能力子集,那么它可能会变得混乱。在这种情况下,您可能只使用一种类型进行运行时检查,以确保您只为每个对象分配允许的能力。
您可以分别对它们建模,然后参考原子能力
定义您的Person/Object类型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