alkjiughh17652
alkjiughh17652

Reputation: 25

Haskell: Compose a function of specific type with one of general type?

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).

Upvotes: 1

Views: 235

Answers (1)

Jan
Jan

Reputation: 11726

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

Upvotes: 5

Related Questions