I was trying to understand what GHCi does to print values, I thought it would just do something like call putStrLn . show
on the value, but then this happened:
a = return 5 :: (Monad m, Num a) => m a
a -- prints 5
b = return 5 :: (Monad m, Num a, Show (m a)) => m a
b -- Ambiguous type variable `m0`...
Why is it that adding the show constraint change this behavior? I thought that'd be assumed when trying to print the value.
By default ghci
works in IO
monad. So when you're trying to evaluate a
its m
type variable becomes IO
. And a
variable has type Num a => IO a
. When you evaluate IO
action inside repl, ghci
just performs it and prints result. In your case this is Num a => a
(and default for polymorphic variables with Num
constraint in ghci
is Integer
data type).
But IO
data type doesn't have Show
instance. There's no such instance and it can't even exist! Before evaluating some expression in ghci
, it should satisfy all constraints. Since it can't satisfy Show (IO a)
(because there's no such instance) it can't substitute IO
for m
type variable. But then: which m
do you exactly want? ghci
can't guess for you. Behaviour is different for different m
s.
ghci> b = return 5 :: (Monad m, Num a, Show (m a)) => m a
ghci> b :: Maybe Int
Just 5
ghci> b :: [Int]
[5]