I don't understand the error message I'm getting or what's wrong with what I'm trying to do
I just want to use List.fold_left to apply my add1 function to this list [1,2,3]
My add1 function should just add 1 to each element, so I would get [2, 3, 4]
My main goal in doing this exercise is just to experiment with List.fold_left. I don't actually care about adding 1, I just choose that function because it seemed easy to write (I'm an ocaml beginner).
My ultimate goal is actually to populate the keys of a empty StringMap using List.fold_left and a function already written elsewhere, so if anyone has insight on that it would also be appreciated
Here's the 1st try (which I tried twice)
let rec add1 = function
| [] -> []
| h::t -> (h+1)::(add1 t) in List.fold_left add1 [1, 2, 3];;
Here's the 2nd try
let a(b) =
let rec add1 = function
| [] -> []
| h::t -> (h+1)::(add1 t)
in
let c = List.fold_left add1 b
in a [1,2,3];;
It may help you to see how fold_left
can be implemented.
let rec fold_left f init lst =
match lst with
| [] -> init
| x::xs -> fold_left f (f init x) xs
So consider what's happening when something like a sum function works, when implemented in term of fold_left
.
let sum lst =
fold_left (+) 0 lst
If we evaluate sum [1; 2; 3; 4]
:
sum [1; 2; 3; 4]
fold_left (+) 0 [1; 2; 3; 4]
fold_left (+) (0 + 1) [2; 3; 4]
fold_left (+) (1 + 2) [3; 4]
fold_left (+) (3 + 3) [4]
fold_left (+) (6 + 4) []
10
We can define map
in terms of fold_left
:
let map f lst =
let f' init x = f x :: init in
fold_left f' [] lst
Let's evaluate map (fun x -> x + 1) [5; 2; 6]
:
map (fun x -> x + 1) [5; 2; 6]
fold_left f' [] [5; 2; 6]
fold_left f' (5 + 1 :: []) [2; 6]
fold_left f' (2 + 1 :: [6]) [6]
fold_left f' (6 + 1 :: [3; 6]) []
[7; 3; 6]
Now, because of the way we destructure and create lists, the result is backwards. we can overcome this with fold_left
by reversing the resulting list.
let map f lst =
let f' init x = f x :: init in
let lst' = fold_left f' [] lst in
List.rev lst'
Or with the |>
operator:
let map f lst =
let f' init x = f x :: init in
lst |> fold_left f' [] |> List.rev
At each iteration, fold_left
transforms the first element in a list and an accumulator, into the accumulator for the next iteration. If you want to apply this concept to your StringMap
module, consider StringMap.empty
which generates an empty StringMap.t
, and StringMap.add
which take a key, an associated value, and an existing map, and returns a new map with that added mapping.
You can readily use fold_left
to take an initially empty map and build it into a complete map step by step. The only question remaining will be what value you choose to associate with each string in your list.