Reputation: 89
I am writing a function to apply a function for next two elements in list.
For example: applyToTwo (+) [1,2,3,4]
return [3,5,7]
.
applyToTwo (-) [7,1,1,1,1]
return [6,0,0,0]
.
I want to generalize the type so it could apply to any type I want. My attempt is:
applyToTwo :: (a -> a -> b) -> [a] -> [a]
applyToTwo f [] = []
applyToTwo f [x] = []
applyToTwo f (x:x1:rest) = f x x1 ++ applyToTwo f (x1:rest)
By the way, are there any way to generalize the number of element to apply so it could apply to 3, 4, 5?
Upvotes: 1
Views: 81
Reputation: 94329
It appears you are simply zipping a list with its tail, so you could use zipWith
:
applyToTwo f xs = zipWith f xs (tail xs)
Upvotes: 8
Reputation: 116139
This should do:
applyToTwo :: (a -> a -> b) -> [a] -> [b]
applyToTwo f [] = []
applyToTwo f [x] = []
applyToTwo f (x:x1:rest) = f x x1 : applyToTwo f (x1:rest)
Generalizing to arbitrary arities should be possible, but it requires some advanced type-level hackery.
Upvotes: 2