Example of the difference between List.fold and List.foldBack - f#

My understanding of the difference between List.fold and List.foldBack is that foldBack iterates over its list in a reverse order. Both functions accumulate a result from the items in the list.
I'm having trouble coming up with a good example where it is preferable to foldBack over a list. In the examples I have come up with, the results are the same for both fold and foldBack, if the function logic does the same thing.
[<Fact>]
let ``List.foldBack accumulating a value from the right to the left``() =
let list = [1..5]
let fFoldBack x acc =
acc - x
let fFold acc x =
acc - x
let foldBackResult = List.foldBack fFoldBack list 0
let foldResult = List.fold fFold 0 list
Assert.Equal( -15, foldBackResult ) // 0 - 5 - 4 - 3 - 2 - 1
Assert.Equal( -15, foldResult ) // 0 - 1 - 2 - 3 - 4 - 5

You don't see a difference in your example because you chose a function such that for any x1 and x2:
(acc - x1) - x2 = (acc - x2) - x1
So it doesn't matter in what order you go through the list, you will get the same result.
List construction is an example of function for which it is not the case:
x1 :: (x2 :: acc) <> x2 :: (x1 :: acc)
So the following will yield different results:
List.fold (fun acc x -> x :: acc) [] [1; 2; 3; 4; 5]
// val it : int list = [5; 4; 3; 2; 1]
List.foldBack (fun x acc -> x :: acc) [1; 2; 3; 4; 5] [];;
// val it : int list = [1; 2; 3; 4; 5]
List.fold starts with an empty result list and goes forward through the input, adding each element to the front of the result list; therefore the final result is in the reverse order.
List.foldBack, on the other hand, goes backward through the input; so each element newly added to the front of the result list was itself to the front in the original list. So the final result is the same list as the original.

Tarmil's answer has already demonstrated the difference between the two in a good, concise manner. I'm going to give an example that uses a somewhat more complex data type. (Actually, if you ignore the naming then my example is a linked list, but you can imagine how it could be expanded to something much more complex.)
The purpose of fold vs. foldBack isn't necessarily obvious when you are computing a scalar value, but when you start using it to build data structures, it becomes clear that most such structures must be built in a particular direction. This is especially true if you use immutable data structures, since you don't have the option of constructing a node and then updating it to point to another node.
In this example, I've defined a structure for a trivial programming language that does nothing but print numbers. It recognizes two instructions, Print and End. Each print instruction stores a pointer to the next instruction. Thus, a program consists of a chain of instructions, each pointing to the next. (The reason I've used this particular example is because, by executing the program, you demonstrate its structure.)
The program uses three different methods of constructing the program from a list of integers. The first, make_list_printer, is defined recursively with no fold, to demonstrate what we're trying to achieve. The second, make_list_printer_foldBack, uses foldBack to achieve the same result. The third, make_list_printer_fold, uses fold to demonstrate how it produces the wrong result.
I've mostly coded in OCaml, not F#, so I apologize if some of the coding conventions used below aren't really considered proper style in F#. I did test it in the F# interpreter, though, and it works.
(* Data structure of our mini-language. *)
type prog =
| End
| Print of int * prog
(* Builds a program recursively. *)
let rec make_list_printer = function
| [] -> End
| i :: program -> Print (i, make_list_printer program)
(* Builds a program using foldBack. *)
let make_list_printer_foldBack ints =
List.foldBack (fun i p -> Print (i, p)) ints End
(* Builds a program in the wrong direction. *)
let make_list_printer_fold ints =
List.fold (fun p i -> Print (i, p)) End ints
(* The interpreter for our mini-language. *)
let rec run_list_printer = function
| End ->
printfn ""
| Print (i, program) ->
printf "%d " i;
run_list_printer program
(* Build and run three different programs based on the same list of numbers. *)
let () =
let base_list = [1; 2; 3; 4; 5] in
let a = make_list_printer base_list in
let b = make_list_printer_foldBack base_list in
let c = make_list_printer_fold base_list in
run_list_printer a;
run_list_printer b;
run_list_printer c
The output that I get when I run this is:
1 2 3 4 5
1 2 3 4 5
5 4 3 2 1

Related

Assignment: this expression was expected to have the type unit

I'm writing some thing really easy, a program that finds all factors of an int. Here is what I have
let factor n=
let ls=[]
for i=1 to n do
if i % n =0 then ls = i::ls
l
If I do this then it pops an error This expression was expected to have the type unit. But I tried to put an expression that prints something after if..then.., which is suppose to return type unit, but it still gives the same error. I am lost about this. Can someone help please? Thanks
You are trying to make ls into a mutable variable nd assign it with =. While this is possible, by using mutable (1) or ref (2) along with <- or := assignment operators, this is generally discouraged in the functional world.
A possibly more idiomatic implementation of the naive algorithm could be:
let factor n =
let rec factorLoop curr divs =
if curr > n then divs
else
if n % curr = 0
then factorLoop (curr+1) (curr::divs)
else factorLoop (curr+1) divs
factorLoop 1 [] |> List.rev
> factor 12;;
val it : int list = [1; 2; 3; 4; 6; 12]
Here the main function defines an inner factorLoop function that is recursive. Recursion is the way we can avoid many uses of mutable variables in functional languages. The recursive inner function threads along a curr variable that is the current divisor to be tested and a list divs of currently found divisors. The result includes 1 and n. This can be altered respectively by changing the initial value of curr and the terminating condition in the first line of factorLoop.
It is worth noting that it can all be shrunk down to one line by making use of the F# library:
let factor n =
[1..n] |> List.filter (fun x -> n % x = 0)
Here we build a list of values 1..n and feed them to List.filter which applies the given predicate (at the end of the line) to select only divisors on n. If n is large, however, the temp list will grow very large. We can use a lazily evaluated sequence instead, which won't blow the memory usage:
let factor n =
{1..n} |> Seq.filter (fun x -> n % x = 0) |> Seq.toList
Here we filter on a 'lazy' sequence and only convert the (much smaller) sequence of results to a list at the end:
> factor 10000000;;
val it : int list =
[1; 2; 4; 5; 8; 10; 16; 20; 25; 32; ... etc
= is comparison, not assignment. You want either
let factor n =
let mutable ls = []
for i = 1 to n do
if n % i = 0 then ls <- i::ls
ls
or
let factor n =
let ls = ref []
for i = 1 to n do
if n % i = 0 then ls := i::(!ls)
!ls
Note, however, that both of these solutions are highly unidiomatic, as there are equally easy immutable solutions to this problem.

How do I append to a list in F# rather than prepend?

Prepending to a list in F# is somewhat annoying because once you're done you have to reverse it. Is there a way to build a list straight from start?
If you need to append elements to the end, you can use the type known as DList. There is an implementation available in FSharpX.
However, there is some runtime overhead associated with this (e.g. see the comments here) and so I think that building list by prepending and then reversing is generally going to be more efficient. It is also quite standard thing to do in functional programming - it may look a bit confusing at first, but it is a very common "design pattern" when implementing recursive functions that walk over lists, so I would not try to avoid it.
There is nothing wrong with prepending and reversing the list. You can use append (#) on a single-element list, but it is a code smell. A tolerable (tail-recursive) approach is:
let appendSingle xs x =
[ yield! xs
yield x ]
All the above solutions have O(n) execution time.
For your use case, you could keep a private ResizeArray to avoid the use of reverse. It is fine since mutability is hidden. Compare this function
let filter f l =
let rec loop acc l =
match l with
| [] -> List.rev acc
| x::xs when f x -> loop (x::acc) xs
| x::xs -> loop acc xs
loop [] l
with its more efficient counterpart
let filter f l =
let rec loop (acc : ResizeArray<_>) l =
match l with
| [] -> Seq.toList acc
| x::xs when f x ->
acc.Add(x)
loop acc xs
| x::xs -> loop acc xs
loop (ResizeArray()) l
Referring back to your original code, I think what you are looking for is to use List.foldBack rather than List.fold. Essentially, foldBack repeatedly applies the folder function starting from the end of the list rather than from the start of the list. It's not as efficient as fold but it's better to use foldBack and avoid reversing the list.
With foldBack, your accumulation function folder is applied to a list x0::x1::...::xlast as follows, where the initial argument to folder isinit:
folder x0 (folder x1 ( ... (folder xlast init) ... ) )
c.f. fold
folder (... (folder (folder init x0) x1) ...) xlast
There are some other answers to your original question that suggest alternative solutions, but sticking with your code, substituting foldBack for fold results in a first implementation
let chunkOrig items chunkSize =
let folder =
fun x (result, chunk) ->
if List.length chunk < chunkSize then
(result, x::chunk)
else
(chunk::result, [x])
let (a,b) = List.foldBack folder items ([], [])
b::a
Already this is a lot simpler, as all the list reversing has gone. And it seems to work.
> chunkOrig [1..10] 2;;
val it : int list list = [[1; 2]; [3; 4]; [5; 6]; [7; 8]; [9; 10]]
However when your list doesn't divide into equal chunks it goes wrong, because foldBack starts from the last element.
> chunkOrig [1..11] 2;;
val it : int list list = [[1]; [2; 3]; [4; 5]; [6; 7]; [8; 9]; [10; 11]]
What you need to do is parameterise your local function folder by the length remaining in the current chunk rather than by the chunk itself.
let chunk items chunkSize =
let folder =
fun x (result, lenLeft) ->
if lenLeft > 0 then
match result with
| [] -> ([[x]], lenLeft-1)
| r0::rtail -> ((x::r0)::rtail, lenLeft-1)
else
([x]::result, chunkSize-1)
let (result, lenLeft) = List.foldBack folder items ([], (List.length items) % chunkSize)
result
> chunk [1..10] 2;;
val it : int list list = [[1; 2]; [3; 4]; [5; 6]; [7; 8]; [9; 10]]
> chunk [1..11] 2;;
val it : int list list = [[1; 2]; [3; 4]; [5; 6]; [7; 8]; [9; 10]; [11]]
Append x to xs like this:
xs # [x]
Note that this is O(n).

Is there a technical difference between placing a second argument on a new indented line vs the same line?

Consider the two examples below:
let myList = [0..10]
List.map (fun x -> x + 5)
(List.filter (fun x -> x % 3 = 0) myList)
and
let myList = [0..10]
List.map (fun x -> x + 5) (List.filter (fun x -> x % 3 = 0) myList)
Both examples produce the same result:
val myList : int list = [0; 1; 2; 3; 4; 5; 6; 7; 8; 9; 10]
val it : int list = [5; 8; 11; 14]
F# being a white-space sensitive language, is there technically a difference between these two examples?
I think F# Code Formatting Guidelines is very helpful for you, especially the first section about General rules for indentation.
Here is a relevant excerpt from the page:
When you break long lines, the continuation of the line must be indented farther than the enclosing construct. For example, function arguments must be indented farther than the first character of the function name, as shown in the following code.
let someFunction param1 param2 =
let result = myFunction1 param1
param2
result * 100
So indentation in the first example helps F# compiler parse your example correctly.
F# being a white-space sensitive language, is there technically a difference between these two examples?
No. Two code fragments have the same meaning here; the only difference is readability. I prefer the first one since my eyes don't have to go to far right to read the whole function.
Sometimes when a line is too long, you could reorder arguments using pipes and break that line to multiple ones:
myList
|> List.filter (fun x -> x % 3 = 0)
|> List.map (fun x -> x + 5)
UPDATE:
I took some time to aggregate information from different sources and wrote up a comprehensive guide to F# Formatting Conventions; you might want to look into it.

Converting a loop to pure functions

I have this code written for a Project Euler problem in c++:
int sum = 0;
for(int i =0; i < 1000; i++)
{
//Check if multiple of 3 but not multiple of 5 to prevent duplicate
sum += i % 3 == 0 && i % 5 != 0 ? i: 0;
//check for all multiple of 5, including those of 3
sum += i % 5 == 0 ? i: 0;
}
cout << sum;
I'm trying to learn f# and rewriting this in f#. This is what I have so far:
open System
//function to calculate the multiples
let multiple3v5 num =
num
//function to calculate sum of list items
let rec SumList xs =
match xs with
| [] -> 0
| y::ys -> y + SumList ys
let sum = Array.map multiple3v5 [|1 .. 1000|]
What I have may be complete nonsense...so help please?
Your sumList function is a good start. It already iterates (recursively) over the entire list, so you don't need to wrap it in an additional Array.map. You just need to extend your sumList so that it adds the number only when it matches the specified condition.
Here is a solution to a simplified problem - add all numbers that are divisible by 3:
open System
let rec sumList xs =
match xs with
| [] -> 0 // If the list is empty, the sum is zero
| y::ys when y % 3 = 0 ->
// If the list starts with y that is divisible by 3, then we add 'y' to the
// sum that we get by recursively processing the rest of the list
y + sumList ys
| y::ys ->
// This will only execute when y is not divisible by 3, so we just
// recursively process the rest of the list and return
/// that (without adding current value)
sumList ys
// For testing, let's sum all numbers divisble by 3 between 1 and 10.
let sum = sumList [ 1 .. 10 ]
This is the basic way of writing the function using explicit recursion. In practice, the solution by jpalmer is how I'd solve it too, but it is useful to write a few recursive functions yourself if you're learning F#.
The accumulator parameter mentioned by sashang is a more advanced way to write this. You'll need to do that if you want to run the function on large inputs (which is likely the case in Euler problem). When using accumulator parameter, the function can be written using tail recursion, so it avoids stack overflow even when processing long lists.
The idea of a accumulator-based version is that the function takes additional parameter, which represents the sum calculated so far.
let rec sumList xs sumSoFar = ...
When you call it initially, you write sumList [ ... ] 0. The recursive calls will not call y + sumList xs, but will instead add y to the accumulator and then make the recursive call sumList xs (y + sumSoFar). This way, the F# compiler can do tail-call optimization and it will translate code to a loop (similar to the C++ version).
I'm not sure if translating from an imperative language solution is a good approach to developing a functional mindset as instrument (C++ in your case) had already defined an (imperative) approach to solution, so it's better sticking to original problem outlay.
Overall tasks from Project Euler are excellent for mastering many F# facilities. For example, you may use list comprehensions like in the snippet below
// multipleOf3Or5 function definition is left for your exercise
let sumOfMultiples n =
[ for x in 1 .. n do if multipleOf3Or5 x then yield x] |> List.sum
sumOfMultiples 999
or you can a bit generalize the solution suggested by #jpalmer by exploiting laziness:
Seq.initInfinite id
|> Seq.filter multipleOf3Or5
|> Seq.takeWhile ((>) 1000)
|> Seq.sum
or you may even use this opportunity to master active patterns:
let (|DivisibleBy|_) divisior num = if num % divisor = 0 the Some(num) else None
{1..999}
|> Seq.map (fun i ->
match i with | DivisibleBy 3 i -> i | DivisibleBy 5 i -> i | _ -> 0)
|> Seq.sum
All three variations above implement a common pattern of making a sequence of members with sought property and then folding it by calculating sum.
F# has many more functions than just map - this problem suggests using filter and sum, my approach would be something like
let valid n = Left as an exercise
let r =
[1..1000]
|> List.filter valid
|> List.sum
printfn "%i" r
I didn't want to do the whole problem, but filling in the missing function shouldn't be too hard
This is how you turn a loop with a counter into a recursive function. You do this by passing an accumulator parameter to the loop function that holds the current loop count.
For example:
let rec loop acc =
if acc = 10 then
printfn "endloop"
else
printfn "%d" acc
loop (acc + 1)
loop 0
This will stop when acc is 10.

Return value in F# - incomplete construct

I've trying to learn F#. I'm a complete beginner, so this might be a walkover for you guys :)
I have the following function:
let removeEven l =
let n = List.length l;
let list_ = [];
let seq_ = seq { for x in 1..n do if x % 2 <> 0 then yield List.nth l (x-1)}
for x in seq_ do
let list_ = list_ # [x];
list_;
It takes a list, and return a new list containing all the numbers, which is placed at an odd index in the original list, so removeEven [x1;x2;x3] = [x1;x3]
However, I get my already favourite error-message: Incomplete construct at or before this point in expression...
If I add a print to the end of the line, instead of list_:
...
print_any list_;
the problem is fixed. But I do not want to print the list, I want to return it!
What causes this? Why can't I return my list?
To answer your question first, the compiler complains because there is a problem inside the for loop. In F#, let serves to declare values (that are immutable and cannot be changed later in the program). It isn't a statement as in C# - let can be only used as part of another expression. For example:
let n = 10
n + n
Actually means that you want the n symbol to refer to the value 10 in the expression n + n. The problem with your code is that you're using let without any expression (probably because you want to use mutable variables):
for x in seq_ do
let list_ = list_ # [x] // This isn't assignment!
list_
The problematic line is an incomplete expression - using let in this way isn't allowed, because it doesn't contain any expression (the list_ value will not be accessed from any code). You can use mutable variable to correct your code:
let mutable list_ = [] // declared as 'mutable'
let seq_ = seq { for x in 1..n do if x % 2 <> 0 then yield List.nth l (x-1)}
for x in seq_ do
list_ <- list_ # [x] // assignment using '<-'
Now, this should work, but it isn't really functional, because you're using imperative mutation. Moreover, appending elements using # is really inefficient thing to do in functional languages. So, if you want to make your code functional, you'll probably need to use different approach. Both of the other answers show a great approach, although I prefer the example by Joel, because indexing into a list (in the solution by Chaos) also isn't very functional (there is no pointer arithmetic, so it will be also slower).
Probably the most classical functional solution would be to use the List.fold function, which aggregates all elements of the list into a single result, walking from the left to the right:
[1;2;3;4;5]
|> List.fold (fun (flag, res) el ->
if flag then (not flag, el::res) else (not flag, res)) (true, [])
|> snd |> List.rev
Here, the state used during the aggregation is a Boolean flag specifying whether to include the next element (during each step, we flip the flag by returning not flag). The second element is the list aggregated so far (we add element by el::res only when the flag is set. After fold returns, we use snd to get the second element of the tuple (the aggregated list) and reverse it using List.rev, because it was collected in the reversed order (this is more efficient than appending to the end using res#[el]).
Edit: If I understand your requirements correctly, here's a version of your function done functional rather than imperative style, that removes elements with odd indexes.
let removeEven list =
list
|> Seq.mapi (fun i x -> (i, x))
|> Seq.filter (fun (i, x) -> i % 2 = 0)
|> Seq.map snd
|> List.ofSeq
> removeEven ['a'; 'b'; 'c'; 'd'];;
val it : char list = ['a'; 'c']
I think this is what you are looking for.
let removeEven list =
let maxIndex = (List.length list) - 1;
seq { for i in 0..2..maxIndex -> list.[i] }
|> Seq.toList
Tests
val removeEven : 'a list -> 'a list
> removeEven [1;2;3;4;5;6];;
val it : int list = [1; 3; 5]
> removeEven [1;2;3;4;5];;
val it : int list = [1; 3; 5]
> removeEven [1;2;3;4];;
val it : int list = [1; 3]
> removeEven [1;2;3];;
val it : int list = [1; 3]
> removeEven [1;2];;
val it : int list = [1]
> removeEven [1];;
val it : int list = [1]
You can try a pattern-matching approach. I haven't used F# in a while and I can't test things right now, but it would be something like this:
let rec curse sofar ls =
match ls with
| even :: odd :: tl -> curse (even :: sofar) tl
| even :: [] -> curse (even :: sofar) []
| [] -> List.rev sofar
curse [] [ 1; 2; 3; 4; 5 ]
This recursively picks off the even elements. I think. I would probably use Joel Mueller's approach though. I don't remember if there is an index-based filter function, but that would probably be the ideal to use, or to make if it doesn't exist in the libraries.
But in general lists aren't really meant as index-type things. That's what arrays are for. If you consider what kind of algorithm would require a list having its even elements removed, maybe it's possible that in the steps prior to this requirement, the elements can be paired up in tuples, like this:
[ (1,2); (3,4) ]
That would make it trivial to get the even-"indexed" elements out:
thelist |> List.map fst // take first element from each tuple
There's a variety of options if the input list isn't guaranteed to have an even number of elements.
Yet another alternative, which (by my reckoning) is slightly slower than Joel's, but it's shorter :)
let removeEven list =
list
|> Seq.mapi (fun i x -> (i, x))
|> Seq.choose (fun (i,x) -> if i % 2 = 0 then Some(x) else None)
|> List.ofSeq

Resources