在F#中创建双向树

问题描述 投票:0回答:1

我正在尝试定义和创建一个树结构,其中父级了解子级,反之亦然。

我创建了以下 F# 代码,它不显示任何警告(在 fsx 中),并且似乎编译得很好。

type Parent = {
    Name : string
    Age : int
    Children : Child list }
and Child = {
    Name : string
    Parent : Parent }    

let createParent name children = 
  { Name = name
    Age = 42
    Children = children }

let createChild name parent = 
  { Name = name
    Parent = parent }

let create name kids =
    let rec makeChild name = createChild name parent
    and makeParent name = createParent name children
    and parent = name |> makeParent 
    and children = kids |> List.map makeChild
    parent

create "Peter" [ "Sarah"; "Max" ]
|> printfn "%A"

但是当我运行这个脚本时,我可以看到“Children”为空。

我是否遗漏了什么,或者这样的数据结构根本无法在 F# 中构建?

recursion functional-programming f#
1个回答
0
投票

我绝不是这个主题的专家,但我认为这是因为 F# 开箱即用的不变性以及您在 Parent 和 Child 之间引入的循环依赖关系。

有一次我正在开发一个项目,该项目在域模型数据模型之间具有这种循环依赖关系。

每次添加新实体时,我都会从域模型开始,但无法完成它,因为它依赖于数据模型。因此,我不得不放弃领域模型,转向数据模型来实现它。但我再次无法完成数据模型的实现,因为它依赖于域模型。因此,我必须返回到域模型来完成该操作,然后再次返回到数据模型以执行相同的操作。

当我编写该代码时,我可以保留一些未完成的部分,即类的实现,但在初始化 F# 记录时不能这样做。

我认为最好的解决方案是设计出循环依赖。
如果这是不可能的,您可以考虑使一个引用可变,例如:

type Parent =
    { Name: string
      Age: int
      mutable Children: Child list option }
and Child =
    { Name: string
      Parent: Parent }

然后做这样的事情:

let create name kids =
    let parent = createParent name None
    let children = kids |> List.map (fun k -> createChild k parent)

    parent.Children <- Some children

    parent
© www.soinside.com 2019 - 2024. All rights reserved.