【问题标题】:Why does foldBack not execute the same side-effects that fold does?为什么 foldBack 不执行与 fold 相同的副作用?
【发布时间】:2016-02-05 07:51:50
【问题描述】:

我正在研究Example of the difference between List.fold and List.foldBack 的答案,试图弄清楚foldfoldBack 之间的区别。我现在了解应用程序顺序的差异,但是我不理解的副作用有差异。

我使用List.foldList.foldBack 进行测试。我的累加器函数基本上等同于::,因此累加顺序很重要。我使用的累加器函数如下:

let f acc x =
  // printfn "Folding %A into %A" x acc  // Side-effect!
  x :: acc

let f2 x acc =
  // printfn "Folding %A into %A" x acc  // Side-effect!
  x :: acc

我从 F# 参考中了解到:

List.fold f [] [1; 2; 3; 4; 5] = (f (f (f (f (f [] 1) 2) 3) 4) 5)

和:

List.foldBack f2 [] [1; 2; 3; 4; 5] = (f2 1 (f2 2 (f2 3 (f2 4 (f2 5 [])))))

两者都应该返回true,并且它们会返回。太好了,我想;我明白它是如何工作的。但为了确保,我取消了 ff2 的副作用行并再次运行 List.fold fList.foldBack f2List.fold f [] [1; 2; 3; 4; 5] 的结果,printfn 行未注释:

Folding 1 into []
Folding 2 into [1]
Folding 3 into [2; 1]
Folding 4 into [3; 2; 1]
Folding 5 into [4; 3; 2; 1]
val it : bool = true

List.foldBack f2 [] [1; 2; 3; 4; 5] 的结果,printfn 行未注释:

val it : bool = true

我期待“将 N 折叠到 [列表]”在这两种情况下都会出现。但是List.fold 执行了它的累加器函数的副作用,而List.foldBack 没有。

为什么fold这两种形式的副作用执行有区别?

【问题讨论】:

    标签: f# fold


    【解决方案1】:

    您的参数顺序错误。

    应该是

    > List.foldBack f2  [1; 2; 3; 4; 5] [];;
    Folding 5 into []
    Folding 4 into [5]
    Folding 3 into [4; 5]
    Folding 2 into [3; 4; 5]
    Folding 1 into [2; 3; 4; 5]
    val it : int list = [1; 2; 3; 4; 5]
    

    【讨论】:

    • 哦,我现在明白了。这更有意义——这样foldBack 以与其累加器函数期望的顺序相同的顺序获取参数(foldBack 中的输入列表在前,累加器函数中的输入项在前)。这么简单的事情错过了。谢谢!
    • 这样做是为了避免错误:通常你的累加器和你的列表是不同的类型,所以如果你弄乱了参数的顺序,它就不会编译。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-12-25
    • 2017-04-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-03
    • 1970-01-01
    相关资源
    最近更新 更多