【问题标题】:Avoid mutation in this example in F#在 F# 中的此示例中避免突变
【发布时间】:2014-11-04 19:42:07
【问题描述】:

来自 OO 背景,当我试图避免突变时,我无法思考如何解决 FP 的简单问题。

let mutable run = true
let player1List = ["he"; "ho"; "ha"]

let addValue lst value =
    value :: lst

while run do
    let input = Console.ReadLine()
    addValue player1List input |> printfn "%A"
    if player1List.Length > 5 then 
        run <- false
        printfn "all done" // daz never gunna happen

我知道在某些情况下使用突变是可以的,但我正在努力训练自己避免将突变作为默认值。话虽如此,有人可以给我看一个上面没有在 F# 中使用突变的例子吗?

最终的结果应该是player1List继续增长,直到item的长度为6,然后退出并打印'all done'

【问题讨论】:

  • 顺便说一句:您的代码实际上不起作用。您需要 run &lt;- false 并且 addValue 应该改变 player1List 并存储新值(否则您只需打印它然后忽略它)。
  • 谢谢,那是一种类型,我改为

标签: f# functional-programming mutation


【解决方案1】:

最简单的方法是使用递归

open System
let rec makelist l = 
    match l |> List.length with
    |6  -> printfn "all done"; l
    | _ -> makelist ((Console.ReadLine())::l)

makelist []

我还删除了一些 addValue 函数,因为在典型的 F# 代码中仅使用 :: 更为惯用。

您的原始代码对于新的 F# 编码器也有一个常见问题,当您需要 run &lt;- false 时使用 run = false。在 F# 中,= 始终用于比较。编译器确实会对此发出警告。

【讨论】:

  • 哈哈,是的,那 = vs
【解决方案2】:

为了可读性,我会从匹配中删除管道,但在最后一个表达式中使用它以避免额外的括号:

open System

let rec makelist l = 
    match List.length l with
    | 6 -> printfn "all done"; l
    | _ -> Console.ReadLine()::l |> makelist

makelist []

【讨论】:

    【解决方案3】:

    正如其他人已经解释的那样,您可以使用递归重写命令式循环。这很有用,因为它是一种始终有效且对函数式编程非常重要的方法。

    另外,F# 提供了一组丰富的库函数来处理集合,它们实际上可以很好地表达您需要的逻辑。所以,你可以这样写:

    let player1List = ["he"; "ho"; "ha"]
    let player2List = Seq.initInfinite (fun _ -> Console.ReadLine())
    let listOf6 = Seq.append player1List list2 |> Seq.take 6 |> List.ofSeq 
    

    这里的想法是创建一个无限惰性序列,从控制台读取输入,将其附加到初始 player1List 的末尾,然后获取前 6 个元素。

    根据您的实际逻辑,您可能会有所不同,但好消息是这可能更接近您想要实现的逻辑...

    【讨论】:

      【解决方案4】:

      在 F# 中,我们使用递归来执行循环。但是,如果您知道需要迭代多少次,则可以像这样使用 F# List.fold 来隐藏递归实现。

      [1..6] |> List.fold (fun acc _ -> Console.ReadLine()::acc) []
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-07-01
        • 1970-01-01
        • 1970-01-01
        • 2020-03-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-02-21
        相关资源
        最近更新 更多