以下代码导致编译器错误," FS0695:此递归绑定使用无效的递归形式混合。"
type Parent =
{ ParentName : string
Children : Child list }
and Child =
{ ChildName : string
Parent : Parent }
let createChild parent childName =
{ ChildName = childName
Parent = parent }
let createParent parentName childNames =
let rec children = childNames |> List.map (fun childName -> createChild parent childName)
and parent = {
ParentName = parentName
Children = children
}
parent
错误消息是什么意思?我该如何更正此代码?
答案 0 :(得分:4)
我不熟悉这个错误,似乎没有记录在任何地方,但这是我可以推测一下它之后可以推测的。
问题似乎在于parent
如何被lambda表达式关闭,而lambda表达式本身就在children
的定义中。这显然抛弃了类型检查器(tc.fs) - 我的猜测是因为children
绑定本身的右侧包含一个表达式(lambda表达式),它本身包含一个递归引用,但真正的原因可能比这更微妙。请注意,如果您反转这样的声明:
let createParent parentName childNames =
let rec parent = {
ParentName = parentName
Children = children }
and children = childNames |> List.map (fun childName -> createChild parent childName)
parent
您还会在绑定children
的行上看到此警告:
警告:通过使用延迟引用,将在运行时检查对定义的对象的此递归引用和其他递归引用的初始化 - 健全性。这是因为您定义了一个或多个递归对象,而不是递归函数。
要解决这个问题,似乎你可以把关闭拉出一个级别:
let createParent parentName childNames =
let rec makeChild n = createChild parent n
and parent = {
ParentName = parentName
Children = children }
and children = childNames |> List.map makeChild
parent
或者将parent
参数加入到createChild
方法的值中(注意makeChild
之后必须声明parent
):
let createParent parentName childNames =
let rec parent = {
ParentName = parentName
Children = children }
and makeChild = createChild parent
and children = childNames |> List.map makeChild
parent
或更简单地这样:
let createParent parentName childNames =
let rec parent = {
ParentName = parentName
Children = children }
and children = childNames |> List.map (createChild parent)
parent
答案 1 :(得分:0)
因为双方都需要是功能而不是属性
请改为尝试:
let createParent parentName childNames =
let rec children names =
names |> List.map (fun childName -> createChild (parent ()) childName)
and parent () = {
ParentName = parentName
Children = children childNames
}
parent ()