gpt4 book ai didi

list - F# 嵌套列表不变性

转载 作者:行者123 更新时间:2023-12-04 17:43:23 25 4
gpt4 key购买 nike

我正在尝试再次选择 F#,但我发现处理不变性非常困难。

在大多数情况下,我发现不变性非常好。但是,我发现处理嵌套集合非常困难。

我想编写一个单用户 GUI 程序。

为简单起见,假设我们有模型:

type Employee = 
{
Name : string
}

type Company =
{
Name : string
Employees : Employee list
}

如果我修改现有的 Employee
let myNewEmployee = { myEmployee with Name = "John Smith" }

我得到一个新的 Employee这很好。然而,这里出现了一系列问题:
  • 我需要删除旧的 myEmployee并添加 myNewEmployee
    公司员工名单。
  • 这会引发列表中的突变,并产生一个新列表。
  • 这迫使我创建一个新的 Company记录为了注入(inject)新的集合,我不得不重建整个公司列表。

  • 换句话说,改变一个员工的名字,让我重建了整个数据结构。

    每次我被难住的时候,我都会发现 F# 有一种不同的、有创意的做事方式。

    我认为我不知道如何以功能方式处理这种情况是我的无知,请赐教;)

    我应该使用其他 F# 库,例如 F# Data 吗?

    TIA,
    大卫

    最佳答案

    我认为答案部分取决于更大的背景——比如你的应用程序的用户界面是如何实现的。您是对的,在公司中修改一个名称需要您生成新列表和新公司记录。如果您在一次调用 List.map 中执行此操作,那还不错。尽管。

    为了简化示例,我添加了 ID类型 int给每位员工:

    let updateName id name company = 
    let newEmployees = company.Employees |> List.map (fun emp ->
    if emp.ID = id then { emp with Name = name } else emp)
    { company with Employees = newEmployees }

    如果您使用的是 Elm 架构之类的东西,那么这可能是一种合理的方法。

    在某些情况下,您可以做更聪明的事情(但这取决于您的场景)。例如,您可以创建一个新类型来表示具有已应用更新列表的公司:
    type Update = 
    | Rename of id:int * newName:string

    type UpdatedCompany =
    { Company : Company
    Updates : Update list }

    现在更改名称只需附加一个新的 Rename更新列表 Updates .当然,一旦需要显示最终的 Company ,您将需要遍历所有员工(如上)并应用更新。但是,如果您在需要获得新的最终 Company 之前进行了大量更新值,这可能是一个不错的技巧。

    关于list - F# 嵌套列表不变性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50697980/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com