Jens
Jens

Reputation: 9416

What is the type of (1 2) in Haskell?

I was playing around with hugs today and got stuck at a very simple question:

λ 1 1
:: (Num a, Num (a -> t)) => t

What would that type be? I am having trouble to read this.

And if it has a type, why? I would guess that the expression 1 1 is ill-formed and thus type-checking fails, which is supported by the Haskell compiler.

Upvotes: 6

Views: 221

Answers (2)

Bakuriu
Bakuriu

Reputation: 102029

No it is not ill-formed. The type is strange and there probably cannot be any meaningful values for which it makes sense but it's still allowed.

Keep in mind that literals are overloaded. 1 is not an integer. It's anything of type Num. Functions are not excluded from this. There is no rule saying a -> t cannot be " a number" (i.e. an instance of Num).

For example you could have an instance declaration like:

instance Num a => Num (a -> b) where
    fromInteger x = undefined
    [...]

now 1 1 would simply be equal undefined. Not very useful but still valid.

You can have useful definitions of Num for functions. For example, from the wiki

instance Num b => Num (a -> b) where
     negate      = fmap negate
      (+)         = liftA2 (+)
      (*)         = liftA2 (*)
      fromInteger = pure . fromInteger
      abs         = fmap abs
      signum      = fmap signum

With this you can write things like:

f + g

where f and g are functions returning numbers.

Using the above instance declaration 1 2 would be equal to 1. Basically a literal used as a function with the above instance is equal to const <that-literal>.

Upvotes: 12

MathematicalOrchid
MathematicalOrchid

Reputation: 62848

In Haskell, 1 doesn't have a fixed type. It is "any numeric type". More exactly, any type that implements the Num class.

In particular, it is technically valid for a function type to be an instance of Num. Nobody would ever do that, but technically it's possible.

So the compiler is assuming that the first 1 is some sort of numeric function type, and then the second 1 is any other number type (maybe the same type, maybe a different one). If we change the expression to, say, 3 6, then the compiler is assuming

3 :: Num (x -> y) => x -> y
6 :: Num x => x
3 6 :: (Num (x -> y), Num x) => y

Upvotes: 5

Related Questions