我是F#的新手,我想在现实世界中建模具有相当复杂的"有一个"关系的东西.在层次结构的顶部有四种类型,A - D,具有以下关系:
A
|
+--A
|
+--B
| |
| +--B
| |
| +--D
| |
| +--D
|
+--C
| |
: +--D
| |
| +--D
:
Run Code Online (Sandbox Code Playgroud)
因此,类型B可以具有A或B的"父",而类型D可以具有B,C或D的父级.
我想使用有区别的联合来约束每种类型的父级,因此不能将它们分配给无效的父级,例如:
type B_Parent = A | B
type D_Parent = B | C | D
Run Code Online (Sandbox Code Playgroud)
然后我想使用记录来模拟每个类型,其中一个字段是父类,例如:
type A = { parent:A_Parent; ... }
type B = { parent:B_Parent; ... }
type C = { parent:C_Parent; ... }
type D = { parent:D_Parent; ... }
Run Code Online (Sandbox Code Playgroud)
C_Parent不是问题,因为它的父类型A是事先声明的.我为A_Parent使用了'A选项'.但我还没有弄清楚如何定义B_Parent和D_Parent,因为它们对自己和其他类型的嵌套依赖?
首先,一件非常重要的事情:当你写的时候
type B_Parent = A | B
Run Code Online (Sandbox Code Playgroud)
您并不是在声明这B_Parent
是一个将两个先前定义的类型A
和结合在一起的DU B
。没有语法。
上面的代码行实际上是在定义两个空的子类型B_Parent
,它们与原始A
and 无关B
。它等效于:
type B_Parent = B_Parent.A | B_Parent.B
Run Code Online (Sandbox Code Playgroud)
为了重用DU中的现有类型,您需要为案例指定一个名称-有效地将它们包装在另一种类型中。因此正确的声明可以是:
type B_Parent = P_a of A | P_b of B
Run Code Online (Sandbox Code Playgroud)
除此以外-正如安东所说,用于定义相互参照类型的关键字是and
。也就是说,最好使此类相互引用尽可能小而紧密。所以我们可以做这样的事情:
type A = { parent:A_Parent; ... }
and A_Parent = P_a of A
| None
type B = { parent:B_Parent; ... }
and B_Parent = P_a of A
| P_b of B
type C = { parent:C_Parent; ... }
and C_Parent = P_a of A
type D = { parent:D_Parent; ... }
and D_Parent = P_b of B
| P_c of C
| P_d of D
Run Code Online (Sandbox Code Playgroud)
我们可以用刚刚A option
的A_Parent
,只是A
对C_Parent
,但我认为,保持案件名称一致将可能使事情变得更具有可读性。
归档时间: |
|
查看次数: |
235 次 |
最近记录: |