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
F# 递归联合类型和列表_F# - Fatal编程技术网

F# 递归联合类型和列表

F# 递归联合类型和列表,f#,F#,我从F#开始,我在上读到了递归联合类型 给出了链接中的示例 类型员工= |个人工作者 |员工名单经理 如何创建Manager类型的值并为其分配工作人员列表 我可以创建类型为Worker的值,如下所示: type Employee = Worker of Person | Manager of Person * Employee list with member this.employees = match this with |

我从F#开始,我在上读到了递归联合类型

给出了链接中的示例

类型员工=
|个人工作者
|员工名单经理
如何创建
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
)。