GHCi具有/不具有Show约束的值的不同行为

YoT*_*LCD 4 polymorphism haskell ghci

我试图理解GHCi打印值的作用,我认为它会像调用putStrLn . show值那样做,但后来发生了这样的事情:

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`...
Run Code Online (Sandbox Code Playgroud)

为什么添加show约束会改变这种行为?我认为在尝试打印价值时会假设.

She*_*rsh 5

默认情况下,ghciIOmonad中工作.所以,当你试图评估a它的m类型变量时IO.和a变量类型Num a => IO a.当你IO在repl中评估动作时,ghci只需执行它并打印结果.在您的情况下,这是Num a => a(并且具有Num约束的多态变量的默认值ghciInteger数据类型).

但是IO数据类型没有Show实例.没有这样的实例,它甚至不存在!在评估某个表达式之前ghci,它应该满足所有约束.因为它不能满足Show (IO a)(因为没有这样的实例),它不能代替IOm类型变量.但那时:m你究竟想要哪一个?ghci无法猜到你.不同m的行为是不同的.

ghci> b = return 5 :: (Monad m, Num a, Show (m a)) => m a
ghci> b :: Maybe Int
Just 5
ghci> b :: [Int]
[5]
Run Code Online (Sandbox Code Playgroud)