值 with/without 显示约束的 GHCi 不同行为
GHCi different behavior for value with/without Show constraint
我试图了解 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`...
为什么添加显示约束会改变此行为?我认为在尝试打印该值时会假设。
默认情况下 ghci
在 IO
monad 中工作。因此,当您尝试计算 a
时,其 m
类型变量变为 IO
。 a
变量的类型为 Num a => IO a
。当您在 repl 中评估 IO
操作时,ghci
只会执行它并打印结果。在您的情况下,这是 Num a => a
(ghci
中具有 Num
约束的多态变量的默认值为 Integer
数据类型)。
但是 IO
数据类型没有 Show
实例。没有这样的实例,它甚至不可能存在!在计算 ghci
中的某些表达式之前,它应该满足所有约束。由于它不能满足 Show (IO a)
(因为没有这样的实例)它不能用 IO
代替 m
类型变量。但是然后:您到底想要哪个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]
我试图了解 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`...
为什么添加显示约束会改变此行为?我认为在尝试打印该值时会假设。
默认情况下 ghci
在 IO
monad 中工作。因此,当您尝试计算 a
时,其 m
类型变量变为 IO
。 a
变量的类型为 Num a => IO a
。当您在 repl 中评估 IO
操作时,ghci
只会执行它并打印结果。在您的情况下,这是 Num a => a
(ghci
中具有 Num
约束的多态变量的默认值为 Integer
数据类型)。
但是 IO
数据类型没有 Show
实例。没有这样的实例,它甚至不可能存在!在计算 ghci
中的某些表达式之前,它应该满足所有约束。由于它不能满足 Show (IO a)
(因为没有这样的实例)它不能用 IO
代替 m
类型变量。但是然后:您到底想要哪个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]