GHCi 如何选择 Monad 类型 class 的实例用于多态操作?

How does GHCi pick an instance of the Monad type class to use for polymorphic actions?

我是 Haskell 的新手,所以这可能是一个菜鸟问题。

当我执行 return 10 >>= return 时,GHCi 显示 10。当我用 :t 检查 return 10 的类型时,它只是说 return 10 :: (Monad m, Num a) => m a,而我做 typeOf return 10 我得到一个错误。

但据我了解,Haskell一定是使用了>>=的一个特定实例来评估return 10 >>= return,所以它使用了哪个实例以及它如何决定哪个实例使用?

这遵循了 GHCi 有点像 IO 的巨大 do 块的想法。每当您输入表达式形式的内容时,它首先会尝试查看结果的类型是否可以特化为 IO a 形式的内容。如果可以,它会执行 IO 操作并打印结果。只有否则它才会打印表达式本身的结果。

要强制 GHCi 转到您想要的任何特定 monad,您可以添加类型注释。请注意 IO 如何得到不同的处理(并且与表达式在没有任何注释的情况下的处理方式相同)。

ghci> return 10 >>= return :: Maybe Int
Just 10
ghci> return 10 >>= return :: [Int]
[10]
ghci> return 10 >>= return :: IO Int
10

顺便说一句,关于选择 Num 的实例存在一个完全不同的问题,而这个问题与默认规则和单态限制有关。