UPDATE – Solution
Thanks to jacobm for his help, I came up with a solution.
// Folding Recursion
let reverse_list_3 theList =
List.fold_left (fun element recursive_call -> recursive_call::element) [] theList;;
I’m learning about the different ways of recursion in OCaml (for class) and for some exercise, I’m writing a function to reverse a list using different recursion styles.
// Forward Recursion
let rec reverse_list_forward theList =
match theList with [] -> [] | (head::tail) -> (reverse_list_1 tail) @ [head];;
// Tail Recursion
let rec reverse_list_tail theList result =
match theList with [] -> result | (head::tail) -> reverse_list_2 tail (head::result);;
Now, I’m trying to write a reverse function using List.fold_left but I’m stuck and can’t figure it out. How would I write this reverse function using folding?
Also, if anyone has good references on functional programming, the different types of recursion, higher-order-functions, etc…, links would be greatly appreciated 🙂
I find it helpful to think of the fold operations as a generalization of what to do with a sequence of operations
fold_right (+) 0applies the+operation right-associatively, using0as a base case:fold_left 0 (+)applies it left-associatively:Now consider what happens if you replace
+with::and0with[]in both right- and left-folds.It may also be useful to think about the way
fold_leftandfold_rightwork as “replacing” the::and[]operators in a list. For instance, the list[1,2,3,4,5]is really just shorthand for1::(2::(3::(4::(5::[])))). It may be useful to think offold_right op baseas letting you “replace”::withopand[]withbase: for instancebecomes
::became+,[]became0. From this perspective, it’s easy to see thatfold_right (::) []just gives you back your original list.fold_left base opdoes something a bit weirder: it rewrites all the parentheses around the list to go the other direction, moves[]from the back of the list to the front, and then replaces::withopand[]withbase. So for instance:becomes
With
+and0,fold_leftandfold_rightproduce the same result. But in other cases, that’s not so: for instance if instead of+you used-the results would be different: 1 – (2 – (3 – (4 – (5 – 0)))) = 3, but (((((0 – 1) – 2) – 3) – 4) – 5) = -15.