在Haskell中,当我们使用do块时,它如何确定要使用哪个单子?
我们知道do块只是语法上的糖。但是,它如何判断它处于哪个一元语境中呢?假设我们不使用在Haskell中,当我们使用do块时,它如何确定要使用哪个单子?,haskell,Haskell,我们知道do块只是语法上的糖。但是,它如何判断它处于哪个一元语境中呢?假设我们不使用它使用相同的通用类型类机制,该机制用于确定要使用哪个+,甚至是要使用什么数字类型来表示文字。就是, 差不多 do return True 不会预测它应该使用的特定monad,而只是被分配类型monad m=>m Bool。该约束表示do块对于任何碰巧实现了Monad类型类的m具有类型m Bool。此外,无论何时使用此块,都将根据其使用的上下文推断特定实例 如果我们使用绑定到特定的Monad的运算符,这
它使用相同的通用类型类机制,该机制用于确定要使用哪个+
,甚至是要使用什么数字类型来表示文字。就是,
差不多
do
return True
不会预测它应该使用的特定monad,而只是被分配类型monad m=>m Bool
。该约束表示do块对于任何碰巧实现了Monad
类型类的m
具有类型m Bool
。此外,无论何时使用此块,都将根据其使用的上下文推断特定实例
如果我们使用绑定到特定的Monad
的运算符,这将迫使类型变得更加特定。例如,如果我们使用modify::(a->a)->states sa->states s()
(为了这里的示例,我正在简化类型),那么这将强制块具有类型states s…
。通常,Haskell会找出最通用的类型,并利用类型类约束来确保所讨论的类型实现适当的操作。也许一些“实用”的示例会有所帮助:
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!
foo1=do
打印5
返回7
--打印属于IO单子。这整件事都在IO里。
foo2x=do
writetVarx7
返回11
--writeTVar属于STM单子。这整件事都在STM里。
foo3=do
设x=5
[1, 2, 3, 4]
--最后一行是一个列表表达式。这整件事都在单子里。
foo4=do
放7
返回9
--put处于单子状态。这整件事都在单子状态。
foo5=do
do块是函数应用程序和lambadas负载的语法糖,因此它只能使用普通类型推断器。