在没有给出上下文的情况下,Haskell 中的 return 5 是什么类型?

What is the type of return 5 in Haskell when no context is given?

this question 中,OP 询问表达式 return 5 的类型是什么,并且已经在该问题中给出了答案:它是一个通用类型,可以通过输入

:t return 5

在 Haskell 解释器中:

return 5 :: (Num a, Monad m) => m a

return的具体实现取决于它出现的上下文:类型推断会将m限制为特定的monad,例如Maybe[] , IO, 依此类推。

我还可以通过指定类型强制解释器选择特定的 monad,例如

Prelude> return 5 :: Maybe Int
Just 5
Prelude> return 5 :: [Int]
[5]

等等。

现在,如果我在不指定类型的情况下键入表达式 return 5,我将得到:

Prelude> return 5
5

这让我很惊讶:我宁愿期望解释器告诉我它不能选择 return 的适当实现,因为它不能推断要使用的单子类型。

所以我的问题是:Haskell 这里使用了哪些具体的 monad?这个 monad 是根据什么标准选择的?

编辑

感谢您的回答!事实上,如果我尝试编译这个程序:

module Main
where

a = return 5

main :: IO ()
main = putStrLn "This program should not compile"

我得到一个错误:

No instance for (Monad m0) arising from a use of `return'
The type variable `m0' is ambiguous
Relevant bindings include
  a :: m0 Integer (bound at invalid_return.hs:4:1)
Note: there are several potential instances:
  instance Monad ((->) r) -- Defined in `GHC.Base'
  instance Monad IO -- Defined in `GHC.Base'
  instance Monad [] -- Defined in `GHC.Base'
  ...plus one other
In the expression: return 5
In an equation for `a': a = return 5

所以它只适用于 GHCi,原因由 Jon 解释。

单子是 IO。这是 GHCi 行为的一个小怪癖。它试图将您的输入类型统一为 IO a;如果成功,它将运行 IO 操作并尝试 show 结果。如果你给它一个 IO 动作以外的东西,它只会尝试 show 这个值。

出于同样的原因,它们产生相同的输出:

Prelude> "hello"
"hello"
Prelude> print "hello"
"hello"