f# - 如何在 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
具有“跳跃”能力的物体。我怎样才能以一种好的方式对此进行建模?我想让它不可能在代码中创建一个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
值。
只要您没有太多的组合,这就可以正常工作 - 如果您有四种不同类型的对象具有不同的能力子集,那么它可能会变得混乱。在这种情况下,您可能只使用一种类型进行运行时检查,以确保您只为每个对象分配允许的能力。
推荐阅读
- string - 用于用户输入的 stol 和 stoi 的 C++ 精度
- c++ - 如果 C++ 使用 cdecl 调用约定,为什么 Godbolt 会显示在 edi 中传递的参数?
- python - 检查输入时出错:预期dense_1_input 的形状为(784,),但得到的数组的形状为(10,)
- python - 如何使用 pandas 导入下三角矩阵?
- r - 如何在 R 中“总结”带有分类变量的列?
- javascript - 转换 BTC 单位并将其反转
- javascript - 导出 unirest req 结束数据时遇到问题
- r - RODBC 使用 EXEC @variable 查询
- delphi - 在 inifiles 中写入 unicode 文本
- algorithm - 是否有适用于所有情况的类型推理系统?