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