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