在这个问题中,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)