当没有给出上下文时,Haskell中返回5的类型是什么?

Gio*_*gio 12 monads haskell

这个问题中,OP询问表达式的类型是什么,return 5并且在该问题中已经给出了答案:它是泛型类型,可以通过键入来验证

:t return 5
Run Code Online (Sandbox Code Playgroud)

在Haskell解释器中:

return 5 :: (Num a, Monad m) => m a
Run Code Online (Sandbox Code Playgroud)

的具体实现return是通过在它出现的上下文确定:类型推断将限制m到特定的单子如Maybe,[],IO,等.

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

Prelude> return 5 :: Maybe Int
Just 5
Prelude> return 5 :: [Int]
[5]
Run Code Online (Sandbox Code Playgroud)

等等.

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

Prelude> return 5
5
Run Code Online (Sandbox Code Playgroud)

这对我来说是非常令人惊讶的:我宁愿期望解释器告诉我它不能选择合适的实现,return因为它无法推断出要使用的monadic类型.

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

编辑

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

module Main
where

a = return 5

main :: IO ()
main = putStrLn "This program should not compile"
Run Code Online (Sandbox Code Playgroud)

我收到一个错误:

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

所以它只适用于GHCi,原因是Jon解释的原因.

Jon*_*rdy 24

monad是IO.这是GHCi行为的一个小怪癖.它试图统一输入的类型IO a; 如果成功,它会运行该IO操作并尝试show结果.如果你给它一个不是一个IO动作的东西,它只是尝试show该值.

出于同样的原因,这些产生相同的输出:

Prelude> "hello"
"hello"
Prelude> print "hello"
"hello"
Run Code Online (Sandbox Code Playgroud)

  • @Giorgio不,`IO Integer`.根据Haskell的正常默认规则,该数字是默认的. (7认同)