繁体   English   中英

F# 中“不可变”列表的混淆

[英]Confusion on "Immutable" lists in F#

完全新手问题。

我仍在尝试掌握 F# 中的“不可变”列表。

让我们假设我有一个“访问”定义为:

module Visit =
    type Model =
        {
            Name: string
        }

    let init row col cel =
        { 
            Name = sprintf "My Name is row: %d col: %d  cel: %d" row  col cel       
        }

现在我定义了一个可能有也可能没有一次访问的“单元格”:

module Cell =
    type Model =
        {
            Visit: Visit.Model option
        }

    let setVisit m =
        { m with Visit = Some( Visit.init 9 9 9) }

最后我定义了一个包含单元格列表的“列”:

module Column =
    type Model =
        {         
            Appointments: Cell.Model list
        }


    let updateCell (m:Model) =
        let newList = m.Appointments |> List.mapi (fun index cell -> if index = 2 then Cell.setVisit cell else cell)
        {m with Appointments = newList }

在 Column 模块中,“updateCell”函数被连接到为第三个单元格调用 Cell.setVisit。 我的意图是替换第三个单元格持有的“访问”的“名称”。 我的简单问题是:

  1. 这是正确的方法吗?
  2. 如果我要替换约会列表,这是否不会更改保存约会列表的“列”? (列是不可变的,对吧?)。

对不起,我的困惑。

TIA

第一:是的,这是一种可以接受但效率低下的列表方式。 请注意,您在每次updateCell调用时都会重建整个列表,即使其中的大多数元素都相同。

我不知道您在实践中希望在您的模型中有多少约会。 如果它明显多于三个,并且您总是更新第三个,那么剪切列表会更有效,然后将其重新粘在一起:

let newList = List.take 2 m.Appointments @ [Cell.setVisit m.Appointments.[2]] @ List.drop 3 m.Appointments

这样只重建了前三个元素,并重用了列表的尾部。

但是,如果您需要随机访问操作,我可以建议改用数组吗? 当然,它们是可变的,但它们为随机访问操作提供了更好的性能。

第二:不,语法{ m with ... }不会改变Column 相反,它会创建一个列 - m的副本,但所有字段都列在后面with更新为新值。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM