F# 递归联合类型和列表
我从F#开始,我在上读到了递归联合类型 给出了链接中的示例F# 递归联合类型和列表,f#,F#,我从F#开始,我在上读到了递归联合类型 给出了链接中的示例 类型员工= |个人工作者 |员工名单经理 如何创建Manager类型的值并为其分配工作人员列表 我可以创建类型为Worker的值,如下所示: type Employee = Worker of Person | Manager of Person * Employee list with member this.employees = match this with |
类型员工=
|个人工作者
|员工名单经理
如何创建Manager
类型的值并为其分配工作人员列表
我可以创建类型为Worker
的值,如下所示:
type Employee = Worker of Person | Manager of Person * Employee list
with
member this.employees =
match this with
| Manager (_, emps) -> emps
| Worker _ -> []
让john={First=“john”;Last=“Doe”}
让工人=工人约翰
但是我不知道如何创建一个jane
类型的Manager
值,将john
指定为员工列表中的一项:
让jane={First=“jane”;Last=“Doe”}
让经理=经理[工人]
这是可行的,但我无法将第一个
和最后一个
从jane
分配到管理器
在本例中,管理器是否意味着根本没有第一个
/最后一个
我必须如何更改经理的类型定义才能同时拥有员工列表
此外,它还看起来像是经理没有成员员工
在创建了经理类型的值之后,我可以访问该成员?根据该类型定义,经理不能有名字/姓氏。类型定义不包括类似的内容
要使Manager
在这方面的工作方式与Worker
类似,只需给它一个Person
值:
type Employee = Worker of Person | Manager of Person * Employee list
然后,您可以创建一个manager Jane:
let manager = Manager ({ First = "Jane"; Last = "Doe" }, [worker])
对于会员员工
,有几件事要说
首先,远离会员。F#首先是功能性的。函数比成员更好(因为我不想在这里讨论的原因)。具有以下功能:
let employees emp =
match emp with
| Manager (_, emps) -> emps
| Worker _ -> ??? // what to return if the employee turned out to be worker?
你马上就能看到一个困难:当员工是经理时
,当然,我们可以退回他们的员工。但是如果它是一个工作者
?那还什么呢
一个合理的建议是返回一个空列表,因为毕竟,员工
没有任何员工为他们工作,对吗
let employees emp =
match emp with
| Manager (_, emps) -> emps
| Worker _ -> []
另一种可能是返回选项
。哪种方法是“正确的”取决于你将如何处理结果,所以只有你才能回答这个问题
但是,如果你绝对坚持要有一个成员(请仔细考虑你为什么需要它),你绝对可以像这样向你的类型添加一个成员:
type Employee = Worker of Person | Manager of Person * Employee list
with
member this.employees =
match this with
| Manager (_, emps) -> emps
| Worker _ -> []
感谢您的详细回答实例成员实际上是一个功能,以实例为例,但具有稍微不同的人体工程学。通常比静态成员或将函数放入具有相同名称的模块中的等效方法更干净。因为你可以很容易地从一种方法转换到另一种方法,你使用哪种方法并不重要,最好的方法取决于将来的使用情况。@charlesrodie事实上,这两种方法并不相互排斥,你可以同时使用这两种方法(F#本身也是如此,你可以使用例如List.length xs
或xs.length
)。