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)
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments