list - F# 嵌套列表不变性

标签 list f# nested

我正在尝试再次选择 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/

    相关文章:

    python - pandas:将具有相同值的连续行分组为一组

    .net - 使用 F# 进行简单的 .NET Web 开发

    cuda - 目前在 F# 上使用 CUDA 的最佳免费选项是什么

    解析矩阵的嵌套 for 循环的时间复杂度

    css - 嵌套 CSS 有哪些问题/缺点?

    python - 嵌套列表到嵌套字典

    python分解一个列表

    python - 使用正则表达式(Python)进行循环,在匹配后附加到列表

    string - 在 F# 中查找字符串序列中所有出现的字符串?

    java - java中的成员嵌套类?