I was writing a quick one-liner in GHCi and tried to compose sum with map. I figured the reason it failed is because map gives output of a general type [b] whereas sum takes in specific input Num a => [a]. However, there is nothing wrong with this code assuming that the output of the map function is type Num b => [b].
I thought writing a restricting type declaration might work (although I guess that prevents you from doing it in GHCi) but it still didn't:
myFunc :: Num b => (a -> b) -> [a] -> b
myFunc = sum . map
Gave me the following error:
Couldn't match expected type `[[a] -> b]'
with actual type `[a] -> [b]'
Expected type: (a -> b) -> [[a] -> b]
Actual type: (a -> b) -> [a] -> [b]
In the second argument of `(.)', namely `map'
In the expression: sum . map
Is there any way to do this? Maybe I am just missing something obvious (new to Haskell).
sum . map
isn't a definition you're looking for. Observe that
(.) :: (b -> c) -> (a -> b) -> a -> c
The dot operator accepts two unary functions. It doesn't work as map
takes two arguments:
map :: (a -> b) -> [a] -> [b]
One of possible solutions would be to explicitly bind map
's first argument:
myFunc :: Num c => (a -> c) -> [a] -> c
myFucc f = sum . map f
Alternatively you could use curry
and uncurry
and achieve the same result.
myFunc = curry $ sum . uncurry map