【发布时间】:2021-03-26 04:14:52
【问题描述】:
我在 F# 中有以下类型:
type Name = string;;
type Sex =
| M // male
| F // female
type YearOfBirth = int;;
type FamilyTree = P of Name * Sex * YearOfBirth * Children
and Children = FamilyTree list;;
//here is an example:
let f1 = P("Larry",M,1920,[P("May",F,1945,[P("Fred",M,1970,[])]);P("Joe",M,1950,[P("Adam",M,1970,[])]);P("Paul",M,1955,[])])
我的任务是创建一个函数:find: Name -> FamilyTree -> returns (found name, sex, year, [List of the names of all their children]
我知道它与相互递归有关,但我不确定如何应用它。 这是我到目前为止写的:
let fstn (f:FamilyTree) =
match f with
|P(n,s,y,c) -> n
let rec find n t = function
|P(n1,s1,y1,cs) -> if n1=n then (n1,s1,y1,List.map (fun x -> fstn x) cs)
else findC n cs
and findC n clist =
match clist with
|[] -> []
|c::cs -> if n = fstn c then find n c
else findC n cs
当我跑步时
find "May" f1;;
我明白了:
error FS0001: This expression was expected to have type
'Name * Sex * YearOfBirth * Name list'
but here has type
''a list'
有谁知道我做错了什么?我知道类型有问题,但我不知道如何解决它。我可以使用我能得到的所有帮助,非常感谢!
【问题讨论】:
-
如果你输入 annotate 你所有的功能,它会很容易弄明白。
-
从函数开始 find 需要两个参数,但实现只需要一个(家谱)。
-
一般提示:为递归类型添加一个 catamorphism 通常会有所帮助。在您的代码中,catamorphism 可以轻松地将当前节点的名称与请求匹配并返回一个选项,该选项将指示父节点停止搜索。