Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Haskell中,当我们使用do块时,它如何确定要使用哪个单子?_Haskell - Fatal编程技术网

在Haskell中,当我们使用do块时,它如何确定要使用哪个单子?

在Haskell中,当我们使用do块时,它如何确定要使用哪个单子?,haskell,Haskell,我们知道do块只是语法上的糖。但是,它如何判断它处于哪个一元语境中呢?假设我们不使用它使用相同的通用类型类机制,该机制用于确定要使用哪个+,甚至是要使用什么数字类型来表示文字。就是, 差不多 do return True 不会预测它应该使用的特定monad,而只是被分配类型monad m=>m Bool。该约束表示do块对于任何碰巧实现了Monad类型类的m具有类型m Bool。此外,无论何时使用此块,都将根据其使用的上下文推断特定实例 如果我们使用绑定到特定的Monad的运算符,这

我们知道do块只是语法上的糖。但是,它如何判断它处于哪个一元语境中呢?假设我们不使用
它使用相同的通用类型类机制,该机制用于确定要使用哪个
+
,甚至是要使用什么数字类型来表示文字。就是, 差不多

 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负载的语法糖,因此它只能使用普通类型推断器。