Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Simple explanation of List.Fold and List.Foldback in F# [duplicate]

Can anyone please explain in a very simple way what is List.Fold and List.Foldback in F#. I have read some few books and tried to search online for a simple explanation I still don't understand it.

-This is not a duplicate question and it has not been answered in the other link.

like image 328
Oluwagbemi Kadri Avatar asked Oct 29 '25 00:10

Oluwagbemi Kadri


1 Answers

The best way to understand it is with an example. Imagine you have list of numbers and you want to find out the total. In imperative programming you could do this:

let numbers = [ 19 ; 52 ; 35 ; 27]

let mutable total = 0
for n in numbers do
    total <- total + n

printfn "%A" total   // 133

it is a good solution but not functional. Lets use List.fold to do the same:

numbers
|> List.fold (fun total n -> total + n) 0
|> printfn "%A"    // 133

voila! If you squint you can recognize the same elements in both solutions.

  • Your state: total
  • Your folder operation that takes the prior state and an element of the list and returns a new state: total + n
  • Your initial value: 0

Lets look at the signature of List.fold:

val List.fold: 
   folder: 'State -> 'T -> 'State ->
   state : 'State  ->
   list  : 'T list 
        -> 'State

See how the elements match up?

List.foldBack is the same but the elements are fed in reverse order. The order of the parameters is also different.


One of the interesting things about fold is that in many cases it can replace a tail recursive function:

If you didn't have List.fold and wanted to implement a totalF function without mutable, how would you do it? You would need recursion, better yet tail recursion:

let rec totalF total ns =
    match ns with
    | []        ->         total
    | n :: tail -> totalF (total + n) tail

numbers
|> totalF 0
|> printfn "%A"    // 133

Again you can see all the elements as before. In fact if we make total + n into a parameter of totalF:

let rec totalF f total ns =
    match ns with
    | []        -> total
    | n :: tail -> totalF f (f total n) tail

numbers
|> totalF (fun total n -> total + n) 0
|> printfn "%A"    // 133

You get fold, the signature and use are the same:

val totalF: 
   f    : 'a -> 'b -> 'a ->
   total: 'a             ->
   ns   : 'b list        
       -> 'a
like image 69
AMieres Avatar answered Oct 31 '25 20:10

AMieres



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!