0

I'm learning Haskell and am trying to define a function that takes two numbers, add them and then mod 3. I can do it in the following way:

Prelude> let g :: Int -> Int -> Int; g = (\x y -> mod (x+y) 3)

But when I try to write it as a composition of two functions, I'm getting an error and am having a hard time interpreting the error message:

Prelude> let g :: Int -> Int -> Int; g = (\x -> mod x 3) . (\x y -> x + y)

<interactive>:72:40:
    No instance for (Integral (Int -> Int))
      (maybe you haven't applied enough arguments to a function?)
      arising from a use of ‘mod’
    In the expression: mod x 3
    In the first argument of ‘(.)’, namely ‘(\ x -> mod x 3)’
    In the expression: (\ x -> mod x 3) . (\ x y -> x + y)

<interactive>:72:46:
    No instance for (Num (Int -> Int))
      (maybe you haven't applied enough arguments to a function?)
      arising from the literal ‘3’
    In the second argument of ‘mod’, namely ‘3’
    In the expression: mod x 3
    In the first argument of ‘(.)’, namely ‘(\ x -> mod x 3)’

What's wrong here? Can't we compose like this?

Charles Gao
  • 679
  • 2
  • 7
  • 13
  • You cannot simply compose those two functions with `(.)`. Let's pretend for a minute that `g = (\z -> mod z 3) . (\x y -> x + y)` is legal. It would be equivalent to `g = \x -> mod (\y -> x + y) 3`. Of course, `mod` expects an `Integral a => a` (e.g. `5`), not a `Num a => a -> a` (e.g. \y -> 2 + y`); that is what the two error messages tell you. [This answer](http://stackoverflow.com/a/5821236/2541573) explains the general problem and a solution to it in more details. – jub0bs Nov 29 '15 at 08:36
  • Look up "currying". What happens is that Haskell has no binary functions, and things like `\x y ->...` are functions taking _one_ argument and returning another function. Since the result is a function, your composition fails. – chi Nov 29 '15 at 09:23

0 Answers0