Haskell 这个简单的链式绑定是如何工作的?

Haskell 这个简单的链式绑定是如何工作的?,haskell,monads,Haskell,Monads,我正在Haskell学习单子,我正在分析这个例子(): 我想了解函数的这一部分发生了什么: \n -> ['a','b'] >>= \ch -> return (n,ch) [1,2] >>= \n -> [n, \n -> ['a','b']] [1,2] >>= ( \n -> [(n,'a'),(n,'b')] ) 据我所知,\ch->return(n,ch)是由\n->['a','b']作为参数组成的,但我不确定这是

我正在Haskell学习单子,我正在分析这个例子():

我想了解函数的这一部分发生了什么:

\n -> ['a','b'] >>= \ch -> return (n,ch)
[1,2] >>= \n -> [n, \n -> ['a','b']]
[1,2] >>= ( \n -> [(n,'a'),(n,'b')] )
据我所知,
\ch->return(n,ch)
是由
\n->['a','b']
作为参数组成的,但我不确定这是如何发生的。我认为它具有以下组合功能:

\n -> ['a','b'] >>= \ch -> return (n,ch)
[1,2] >>= \n -> [n, \n -> ['a','b']]
[1,2] >>= ( \n -> [(n,'a'),(n,'b')] )
但这似乎并没有产生与完整表达式相同的结果

编辑1:

考虑到完整括号下方的答案:

[1,2] >>= ( \n -> ( ['a','b'] >>= \c -> return (n,c) ) )
这让我获得了这个组合函数:

\n -> ['a','b'] >>= \ch -> return (n,ch)
[1,2] >>= \n -> [n, \n -> ['a','b']]
[1,2] >>= ( \n -> [(n,'a'),(n,'b')] )

事实上这有点不同。括号如下

[1,2] >>= (\n -> ['a','b'] >>= (\ch -> return (n,ch)))
或者,如果你愿意的话

let step1 n = 
  let step2 ch = return (n, ch)
  in ['a','b'] >>= step2
in [1,2] >>= step1

事实上这有点不同。括号如下

[1,2] >>= (\n -> ['a','b'] >>= (\ch -> return (n,ch)))
或者,如果你愿意的话

let step1 n = 
  let step2 ch = return (n, ch)
  in ['a','b'] >>= step2
in [1,2] >>= step1

注意术语“部分评估”。这是一个与这里发生的任何事情无关的技术术语。(这是一种优化技术。)将术语更正为我认为能够正确反映行为的术语。小心术语“部分评估”。这是一个与这里发生的任何事情无关的技术术语。(这是一种优化技术。)将术语更正为我认为正确反映行为的术语。好的。现在我看到完整的括号是:
[1,2]>=(\n->(['a','b']>=\c->return(n,c))
。但是如果我尝试部分地编写它,我想我会得到:
[1,2]>=(\n->[(n,['a','b']))
,但这似乎没有意义。你能告诉我评估是如何进行的吗?我的意思是简单列举发生的步骤。诀窍是,像这样的部分构图必须通过“从外部剥离层”来完成。一元结合序列中的后几步都是有意义的,但前几步没有意义。。。至少,除非用
return
填充该漏洞。在上面的第二个代码段中,
step2
中的
n
实际上是未绑定的。Ok。现在我看到完整的括号是:
[1,2]>=(\n->(['a','b']>=\c->return(n,c))
。但是如果我尝试部分地编写它,我想我会得到:
[1,2]>=(\n->[(n,['a','b']))
,但这似乎没有意义。你能告诉我评估是如何进行的吗?我的意思是简单列举发生的步骤。诀窍是,像这样的部分构图必须通过“从外部剥离层”来完成。一元结合序列中的后几步都是有意义的,但前几步没有意义。。。至少,除非用
return
填充这个洞。在上面的第二个代码段中,
step2
中的
n
实际上是未绑定的。