Haskell 为什么使用“=\x->e; Ee′;新行是e>>e'; 设x=。。。;e就是它的本来面目:让x=。。。在doe;

Haskell 为什么使用“=\x->e; Ee′;新行是e>>e'; 设x=。。。;e就是它的本来面目:让x=。。。在doe;,haskell,monads,Haskell,Monads,因此,我的书给出了计算功率集的以下代码: filterM :: Monad m => (a -> m Bool) -> [a] -> m [a] filterM p [] = return [] filterM p (x:xs) = do b <- p x ys <- filterM p xs return (if b then x:ys else ys) filterM

因此,我的书给出了计算功率集的以下代码:

filterM :: Monad m => (a -> m Bool) -> [a] -> m [a]
filterM p [] = return []
filterM p (x:xs) = do b <- p x
                      ys <- filterM p xs
                      return (if b then x:ys else ys)

filterM (\x -> [True,False]) [1,2,3]
结果:[[1,2,3],[1,2],[1,3],[1],[2,3],[2],[3],]

我只是不知道p为[True,False]的结果如何可以作为b然后x:ys或者ys的回报

直观地说,我猜这个filterM应用列表b的方式是返回所有可能的排列。那就是x:ys和ys。但我只是不知道它发生在哪里


看来我是误会了。但我不明白这将如何导致b的多个实例。

我的错误是解释=运算符,其中:


因此,b不是[True,False],而是在计算剩余部分的每次迭代中使用True和False进行恢复。如果为真,则生成有效的x:ys else ys;如果为假,则生成有效的x:ys else ys

我的错误是解释=运算符,其中:


因此,b不是[True,False],而是在计算剩余部分的每次迭代中使用True和False进行恢复。如果为真,则生成有效的x:ys else ys;如果为假,则生成有效的x:ys else ys

我知道您已经回答了自己的问题,但我认为添加一些关于do符号其他部分实现的信息可能会很有趣。 因此:

x>=\x->e; Ee′;新行是e>>e'; 设x=。。。;e就是它的本来面目:让x=。。。在doe; 因此,程序的递归分支实际上如下所示:

filterM p (x:xs) = p x >>= \b ->
                   filterM p xs >>= \ys ->
                   return (if b then x:ys else ys)

尽管我让我的答案看起来像一个完整的列表,但它肯定不是。例如,如果启用RecursiveDo,您将获得一个新的语法糖层:众所周知的mfix函数位于rec关键字和mdo表示法的下面。我相信还有其他一些例子并没有在我的脑海中一下子浮现出来

我知道您已经回答了自己的问题,但我认为添加一些关于do符号其他部分实现的信息可能会很有趣。 因此:

x>=\x->e; Ee′;新行是e>>e'; 设x=。。。;e就是它的本来面目:让x=。。。在doe; 因此,程序的递归分支实际上如下所示:

filterM p (x:xs) = p x >>= \b ->
                   filterM p xs >>= \ys ->
                   return (if b then x:ys else ys)

尽管我让我的答案看起来像一个完整的列表,但它肯定不是。例如,如果启用RecursiveDo,您将获得一个新的语法糖层:众所周知的mfix函数位于rec关键字和mdo表示法的下面。我相信还有其他一些例子并没有在我的脑海中一下子浮现出来

的确如此。列表单子的目的是为不确定性建模。您可以将do构造视为分叉成多个并行组合,其中b在每个分支中的值与Px不同。每个分支的结果都隐式地连接回一个列表中。列表单子的目的是为不确定性建模。您可以将do构造视为分叉成多个并行组合,其中b在每个分支中的值与Px不同。每个分支的结果都隐式连接回一个列表。do{b do{b