为什么foldBack没有执行折叠相同的副作用?

rmu*_*unn 2 f# fold

我是通过回答工作的不同的实例之间List.fold和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
Run Code Online (Sandbox Code Playgroud)

我从F#参考中了解到:

List.fold f [] [1; 2; 3; 4; 5] = (f (f (f (f (f [] 1) 2) 3) 4) 5)
Run Code Online (Sandbox Code Playgroud)

和:

List.foldBack f2 [] [1; 2; 3; 4; 5] = (f2 1 (f2 2 (f2 3 (f2 4 (f2 5 [])))))
Run Code Online (Sandbox Code Playgroud)

两者都应该回归true,他们会回来.很好,我想; 我明白它是如何工作的.但只是为了确保,我取消了ff2/ List.fold fList.foldBack f2再次运行的副作用线.结果List.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
Run Code Online (Sandbox Code Playgroud)

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

val it : bool = true
Run Code Online (Sandbox Code Playgroud)

在这两种情况下,我都期待"折叠N进入[列表]".但是List.fold执行了累加器功能的副作用,并List.foldBack没有.

为什么两种形式的副作用执行存在差异fold

Joh*_*mer 6

您的参数顺序错误.

它应该是

> 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]
Run Code Online (Sandbox Code Playgroud)

  • 这样做是为了避免错误:通常你的累加器和你的列表将是不同的类型,所以如果你弄乱了参数的顺序,它将无法编译. (2认同)