Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Inheritance 歧视性结合和继承_Inheritance_F#_Discriminated Union - Fatal编程技术网

Inheritance 歧视性结合和继承

Inheritance 歧视性结合和继承,inheritance,f#,discriminated-union,Inheritance,F#,Discriminated Union,我想为我的F#项目创建一个场景图,比如: root ->player_bob -->torch ->enemy_1 -->extravagant_hat -->enemies_cat_jess --->fleas --->fur_ball ->loot let rec traverse tree = // Do something with tree.Object for child in tree.Children do trave

我想为我的F#项目创建一个场景图,比如:

root
->player_bob
-->torch
->enemy_1
-->extravagant_hat
-->enemies_cat_jess 
--->fleas
--->fur_ball
->loot
let rec traverse tree = 
  // Do something with tree.Object
  for child in tree.Children do traverse child
等等等等

每个物品都需要包含一组游戏对象,以表示其子项

e、 Genemy1的列表包含一只猫和一顶帽子,猫列表包含跳蚤和一个皮球

所以我计划让它们都继承自一个类,该类包含一个描述对象子对象的集合

现在回答我的问题: 我是否应该将子对象向下转换到GameObject并将其存储在“GameObject”基类的列表中 或者创建一个有区别的联盟,例如

type SceneObject = 
        |Character of Character //e.g player, enemy, cat
        |Item of Item //e.g hat, torch, furball
并将对象存储为“场景对象”列表,以避免向上投射对象时出现任何问题/开销等,同时允许我描述对象未渲染和/或未用于碰撞检测的特殊情况,例如:声音发射器、陷阱触发器等

有区别的联合+继承组合是我最初的想法;尽管如此,由于我是FP新手,我认为向专业人士寻求最佳、实用的方法是明智的

谢谢


JD

您可以递归地使用区分的并集


Dario建议的另一种方法是为游戏中的实际对象(如项目和角色)声明一个单独的类型,并将其包装在另一个对象中,以添加子对象列表。这看起来像这样:

type SceneObject =
  | Character of <characterData>
  | Item of <itemData>

type ObjectWithChildren = 
  { Object : SceneObject
    Children : ObjectWithChildren list }

在这个版本中,您根本不需要在
SceneObject
上进行模式匹配,因此您不需要包含所有的案例(例如
项目
字符
)。

!这消除了继承的必要性:,)谢谢Dario,我学习FP的一半问题是把我的头从OO土地上拔出来。很有趣。这就是我建模角色类及其状态机的方式。保存所有原始数据(位置、运行状况等)的字符记录(CharacterRecord)。作为状态机的邮箱处理器(CharacterStateMachine)。然后将两者包装在保存{state:CharacterStateMachine;data:CharacterRecord}的“Character”记录中。然后使用成员生成一些用户友好的getter和setter。。。因此,此解决方案非常适合我当前的模型。这两个我都要试一下,非常感谢。
type SceneObject =
  | Character of <characterData>
  | Item of <itemData>

type ObjectWithChildren = 
  { Object : SceneObject
    Children : ObjectWithChildren list }
let rec traverse tree = 
  // Do something with tree.Object
  for child in tree.Children do traverse child