作者:手机用户2602933613 | 来源:互联网 | 2023-01-28 14:28
我们知道do块只是语法糖.但是,它如何确定它所处的monadic背景?假设我们不在<-
do块中的任何地方使用运算符.
1> Daniel Gratz..:
它使用相同的通用类型类机制,用于确定+
要使用的文本或甚至用于文字的数字类型.就是这样的
do
return True
不会认定它应该使用的特定monad,而只是分配类型Monad m => m Bool
.这种约束说,DO-块具有类型m Bool
为任何 m
恰好已经实现了Monad
型类.此外,每当使用此块时,将从其使用的上下文推断出特定实例.
如果我们使用绑定到特定的运算符Monad
,这将强制类型变得更具体.例如,如果我们使用modify :: (a -> a) -> State s a -> State s ()
(我在这里为了示例而简化类型),那么这将强制块具有类型State s ...
.通常,Haskell将找出最常用的类型,并使用类型类约束来确保所讨论的类型实现适当的操作.
2> Mathematical..:
也许一些"实用"的例子会有所帮助:
foo1 = do
print 5
return 7
-- print belongs to the IO monad. This whole thing is in IO.
foo2 x = do
writeTVar x 7
return 11
-- writeTVar belongs to the STM monad. This whole thing is in STM.
foo3 = do
let x = 5
[1, 2, 3, 4]
-- Last line is a list expression. This whole thing is in the list monad.
foo4 = do
put 7
return 9
-- put is in the State monad. This whole thing is in the state monad.
foo5 = do
x <- magic1
y <- magic2
return (x, y)
-- This is in whatever monad magic1 and magic2 are in.
foo6 = do
return 13
-- Doesn't mention any monad. Works for ALL POSSIBLE MONADS!
foo7 abc def = do
x <- abc
y <- def
return (x, y)
-- Runs in whatever monad abc and def run in.
-- By passing different arguments, you can CHANGE which monad that is!