This is probably a stupid question, but why does this function
myTest :: (Bounded a) => a
myTest = minBound :: a
not typecheck?
This works
myTest' :: Int
myTest' = minBound :: Int
and they seem the same to me, except that one would have to type the former (e.g. myTest :: Int) in order for it to work.
The error I get is
• Could not deduce (Bounded a1) arising from a use of ‘minBound’
from the context: Bounded a
bound by the type signature for:
myTest :: Bounded a => a
You must enable ScopedTypeVariables
using {-# LANGUAGE ScopedTypeVariables #-}
, which allows you to use type variables from the function signature inside the function itself. You will also need to change your example as follows:
{-# LANGUAGE ScopedTypeVariables #-}
myTest :: forall a. (Bounded a) => a
myTest = minBound :: a
The forall
tells the compiler to scope the a
. Definitions with no explicit forall
with have the default (unscoped) behavior.
Otherwise, the a
inside the function is a different a
(changed to a1
by the compiler) than the one in the main type signature. It can't deduce that a1
is Bounded from only the context that some other type a
is bounded.
The second example works because Int
is not a type variable, it is a concrete type, which means that it refers to the same type regardless of what type variables are or are not in scope.
Further Reading
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With