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.
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)
In essence, this is a zip rather than a fold. Nicest would be
> zipWith ($) (cycle funclist) charlist
[(65+), (66-), (67*), (68+), (69-), (70+)]
but because of left-associativity and initial element we need to do it a bit more wordy
> let ptApplied = tail . zipWith (($) . flip) (cycle funclist) $ charlist
ptApplied = [(+66), (subtract 67), (*68), (+69), (subtract 70)]
Only then comes the fold
> foldl' (flip ($)) (head charlist) ptApplied
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With