0
votes

http://i.imgur.com/NGKpHbJ.png thats the image of the output ^ . the declarations are here:

let add1 x = x + 1
let multi2 x = x * 2
let wtf x = ((add1 multi2) x)
(wtf 3)

<interactive>:8:1:
    No instance for (Num (a0 -> a0)) arising from a use of `it'
    In a stmt of an interactive GHCi command: print it
?>

Can anyone explain to me why Haskell says that the type of the invalid expression is Num and why it wont print the number? I can't understand what is going on on the type system.

2
It would be nice if you can insert your code and error message here.Sibi
The code I added, but I need you to see the output and error. I cant copy from GHCi.Oded
@Oded You can copy from Windows' command line window by right clicking, then selecting "mark" from the context menu, marking the area you want to copy, right clicking again and then selecting "copy".sepp2k
I have pasted output from GHCi into the question for you.DNA

2 Answers

2
votes

add1 multi2 applies add1 to a function, but add1 expects a number. So you might expect this to be an error because functions aren't numbers, but the thing is that they could be. In Haskell a number is a value of a type that's an instance of the Num type class and you can add instances whenever you want.

That is, you can write instance Num (a -> a) where ... and then functions will be numbers. So now mult2 + 1 will do something that produces a new function of the same type as mult2 (what exactly that will be depends on how you defined + in the instance of course), so add1 mult2 produces a function of type Num a -> a -> a and applying that function to x gives you a value of the same type as x.

So what the type wtf :: (Num (a -> a), Num a) => a -> a is telling you is "Under the condition that you a is a numeric type and you define an instance for Num (a -> a)", wtf will take a number and produce a number of the same type. And when you then actually try to use the function, you get an error because you did not define an instance for Num (a -> a).

0
votes

(Re-written somewhat in response to comment)

Your line of code:

((add1 multi2) x)

means: apply the add1 function to the argument multi2, then apply the resulting function to the argument x. Since adding 1 to a function doesn't make sense, this won't work, so we get a compile-time type error.

The error is explaining that the compiler cannot find a typeclass instance to make functions work like numbers. Numbers must be part of the Num typeclass so they can be added, multiplied etc.

No instance for (Num (a0 -> a0)

In other words, the type a0-> a0 (which is a function type) doesn't have a Num typeclass instance, so adding 1 to it fails. This is a compile-time error; the code is never executed, so GHCi cannot print any output from your function.

The type of your wtf function is:

wtf :: (Num (a -> a), Num a) => a -> a

which says:

  • Given that a is a numeric type
  • and a -> a (function) is a numeric type
  • then wtf will take a number and return a number

The second condition fails at compile time because there's no defined way to treat a function as a number.