haskell - 带/不带显示约束的 GHCi 值的不同行为

标签 haskell polymorphism ghci

我试图了解 GHCi 是如何打印值的,我认为它只会做类似 call putStrLn 的事情。在值上显示,但随后发生了这种情况:

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

为什么添加显示约束会改变这种行为?我认为在尝试打印该值时会假设这一点。

最佳答案

默认情况下,ghciIO monad 中工作。因此,当您尝试计算 a 时,其 m 类型变量将变为 IOa 变量的类型为 Num a => IO a。当您在 repl 中评估 IO 操作时,ghci 只会执行它并打印结果。在您的情况下,这是 Num a => a (在 ghci 中具有 Num 约束的多态变量的默认值为 Integer 数据类型)。

但是 IO 数据类型没有 Show 实例。这样的事例根本不存在,也不可能存在!在计算 ghci 中的某个表达式之前,它应该满足所有约束。由于它不能满足 Show (IO a) (因为没有这样的实例),因此它不能用 IO 替换 m 类型变量。但接下来:您到底想要哪一个mghci 无法为您猜测。不同m的行为是不同的。

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

关于haskell - 带/不带显示约束的 GHCi 值的不同行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50732354/

相关文章:

haskell - Julia 是否有类似于 Haskell 的美元符号的运算符?

haskell - 没有 (Show ([(Char, Char)] -> Char)) 的实例

Haskell:打印函数内变量的类型

haskell - GHC 7.4.1 的约束类型语法是什么?

haskell - 使用折叠将字符串拆分为给定长度的字符串列表

haskell - 是否有像 `fromNewtype . f . toNewtype` 这样的操作的简写?

c++ - 基类指针,基于派生类型调用方法

C# 泛型和多态性 : an oxymoron?

C++使用基类指针访问派生类方法

haskell - 使用快速检查