Folding in Haskell, using more than one function

accumulate, fold, haskell

Solution

Whilst `foldl` may only apply one function, you can have different functions in your data. The trick it to attach the appropriate `+`, `-` or `*` function to your data. You're off to the right start:

funclist = [(+), (-), (*)]

But lets now make a infinite version of the above list, like `[(+), (-), (*), (+), (-), (*)...]`

infinite_funclist = cycle funclist

Lets assign the numbers we're going to fold over here. `first` is in this case `65`, `rest` is `[66..70]`

(first:rest) = [65..70]

Now we zip together `rest` and `infinite_funclist` to get `[(66,(+)), (67,(-)), (68,(*)), (69,(+)), (70,(-))]`. We start with `first`, and for every new element, we apply the operation that's in the second part of the current tuple to the current value and the first part like so:

result = foldl' (\acc (v, f) -> acc `f` v) first (zip rest infinite_funclist)

If we want to print the result we can do so like so:

main = print result

(Link to code here)

Problem

I have a list of integers based on letters. For example: ``` let charlist = map (ord) "ABCDEF" ``` `charlist` would then look like the following: ``` [65,66,67,68,69,70] ``` I also have a list of three functions: `(+)`, `(-)` and `(*)`. The list in this example looks like this ``` let funclist = [(+), (-), (*)] ``` I want to apply the functions in order between the elements in `charlist` (if there are more "spaces" in `charlist` than there are elements in `funclist`, you start over from the beginning of `funclist`) and calculate the final value from left to right, like the following: ``` s = ((((((65) + 66) - 67) * 68) + 69) - 70) ``` I was thinking about using `foldl`, but `foldl` seems to only work with one function. Is there any other way to do this? I would like to summarize this entire process in one function, if possible, though it's not a requirement.

Original source