在没有上下文的情况下,Haskell中的return 5的类型是什么?
在此问题中,OP询问表达式的类型 return 5
是,并且已经在该问题中给出了答案:它是通用类型,可以通过键入来验证
In this question the OP asks what the type of the expression return 5
is and the answer has already been given in that question: it is a generic type, as can be verified by typing
:t return 5
在Haskell解释器中:
in the Haskell interpreter:
return 5 :: (Num a, Monad m) => m a
return
的具体实现取决于它出现的上下文:类型推断会将 m
限制为特定的monad,例如 Maybe
, []
, IO
等.
The specific implementation of return
is determined by the context in which it appears: type inference will restrict m
to a specific monad such as Maybe
, []
, IO
, and so on.
我还可以通过指定类型来强制解释器选择特定的monad.
I can also force the interpreter to pick a specific monad by specifying the type, e.g.
Prelude> return 5 :: Maybe Int
Just 5
Prelude> return 5 :: [Int]
[5]
以此类推.
现在,如果我输入表达式 return 5
而未指定类型,则会得到:
Now if I type the expression return 5
without specifying a type, I get:
Prelude> return 5
5
这让我感到很惊讶:我希望解释器告诉我它不能选择 return
的适当实现,因为它不能推断要使用的单子类型.
which is quite surprising to me: I would rather have expected the interpreter to tell me that it cannot pick an appropriate implementation of return
because it cannot infer the monadic type to be used.
所以我的问题是:Haskell在这里使用了什么特定的monad?而这个单子是根据什么标准选择的呢?
So my question is: what specific monad has Haskell used here? And based on what criteria was this monad chosen?
编辑
感谢您的回答!实际上,如果我尝试编译该程序:
Thanks for the answer! In fact, if I try to compile this program:
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
因此,仅出于乔恩(Jon)解释的原因,它只能在GHCi中工作.
So it only works in GHCi for the reasons explained by Jon.
monad是 IO
.这是GHCi行为的一个小怪癖.它尝试使用 IO a
统一输入的类型;如果成功,它将运行该 IO
操作并尝试 show
结果.如果您给它一个 IO
动作以外的东西,它只会尝试显示
值.
The monad is IO
. This is a minor quirk of the behaviour of GHCi. It tries to unify the type of your input with IO a
; if it succeeds, it runs that IO
action and tries to show
the result. If you give it something other than an IO
action, it simply tries to show
the value.
出于相同的原因,它们产生相同的输出:
It’s for the same reason that these produce the same output:
Prelude> "hello"
"hello"
Prelude> print "hello"
"hello"