Search code examples
haskellfunction-compositionpointfree

Haskell currying to remove argument variable at the end


I am a newbie trying to learn haskell, I tried to search for something similar in other forums but couldn't find a similar question.

addPoly :: (Num a)=>[[a]]->[a]
addPoly  x = map sum $ transpose x

runs fine

but when I remove x at the end it errors out

addPoly :: (Num a)=>[[a]]->[a]
addPoly  = map sum $ transpose 

errors saying:

Couldn't match expected type `[[Integer]] -> [Integer]'
            with actual type `[Integer]'
In the expression: map sum $ transpose
In an equation for `addPoly': addPoly = map sum $ transpose

Couldn't match expected type `[[Integer]]'
            with actual type `[[a0]] -> [[a0]]'
In the second argument of `($)', namely `transpose'
In the expression: map sum $ transpose
In an equation for `addPoly': addPoly = map sum $ transpose

Couldn't figure out what I am missing here.

Disclaimer: this is not a homework problem


Solution

  • $ is defined in Haskell as

    f $ x = f x
    infixr 0 $
    

    So if you expand the first snippet of your code,

    map sum $ transpose x
    

    becomes

    map sum (transpose x)
    

    which will work.

    But the second snippet

    map sum $ transpose 
    

    becomes

    map sum transpose
    

    and when you call that with x, you get

    map sum transpose x
    

    which actually map's sum over transpose (and calls the result with argument x, which also doesn't make sense, and causes the error message you get, as map will return a List, not a function), and not over transpose x.

    You need to use the . function for this, instead of $, which is defined as

    (.) f g = \x -> f (g x)
    

    If you do that, your code

    map sum . transpose
    

    becomes

    \x -> map sum (transpose x)
    

    and when you call this from on some parameter x, it simply becomes

    map sum (transpose x)
    

    which is the (correct) code we started with.

    Let me know if something isn't clear.