问题
I was working through the answers to Example of the difference between List.fold and List.foldBack trying to get my head around the difference between fold
and foldBack
. I understand the difference in application order now, but there's a difference in side-effects that I don't understand.
I used List.fold and List.foldBack for my testing. My accumulator functions that were basically equivalent to ::
, so that accumulation order would matter. The accumulator functions I used were as follows:
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
I understand from the F# reference that:
List.fold f [] [1; 2; 3; 4; 5] = (f (f (f (f (f [] 1) 2) 3) 4) 5)
and:
List.foldBack f2 [] [1; 2; 3; 4; 5] = (f2 1 (f2 2 (f2 3 (f2 4 (f2 5 [])))))
should both return true
, and they do. Great, I thought; I understand how it works. But just to make sure, I uncommented the side-effect lines from f
and f2
and ran List.fold f
and List.foldBack f2
again. Result of List.fold f [] [1; 2; 3; 4; 5]
with the printfn
line uncommented:
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
Result of List.foldBack f2 [] [1; 2; 3; 4; 5]
with the printfn
line uncommented:
val it : bool = true
I was expecting "Folding N into [list]" to show up in both cases. But List.fold
executed the side effects of its accumulator function, and List.foldBack
did not.
Why is there a difference in side-effect execution between the two forms of fold
?
回答1:
You have the arguments in the wrong order.
It should be
> 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]
来源:https://stackoverflow.com/questions/35218872/why-does-foldback-not-execute-the-same-side-effects-that-fold-does