Haskell 一元滤波器与折叠的关系

Haskell 一元滤波器与折叠的关系,haskell,monads,fold,Haskell,Monads,Fold,许多高阶函数可以用折叠函数来定义。例如,这里是Haskell中filter和foldl之间的关系 myFilter p [] = [] myFilter p l = foldl (\y x -> if (p x) then (x:y) else y) [] (reverse l) 它们的一元版本filterM和foldM之间是否存在类似的关系?如何根据foldM编写filterM 我试图找到一个相当于\yx->if(px)then(x:y)else y的单子插入foldM,但没有成功。不

许多高阶函数可以用
折叠
函数来定义。例如,这里是Haskell中
filter
foldl
之间的关系

myFilter p [] = []
myFilter p l = foldl (\y x -> if (p x) then (x:y) else y) [] (reverse l)
它们的一元版本
filterM
foldM
之间是否存在类似的关系?如何根据
foldM
编写
filterM


我试图找到一个相当于
\yx->if(px)then(x:y)else y
的单子插入
foldM
,但没有成功。

不确定它是否有任何意义(因为它有那种奇怪的
反向
),但至少它的类型检查得很好:

myFilterM::Monad m=>(a->m Bool)->[a]->m[a]
myFilterM p l=foldM f[](反向l)
哪里
f y x=do

p1与D.M.的答案类似,只是没有
反向
。让类型引导您:

import Control.Monad
{-
foldM   :: (Monad m) => (b -> a -> m b) -> b -> [a] -> m b
filterM :: (Monad m) => (a -> m Bool)        -> [a] -> m [a]
-}

filtM :: (Monad m) => (a -> m Bool) -> [a] -> m [a]
filtM p xs = foldM f id xs >>= (return . ($ [])) 
  where 
    f acc x = do t <- p x 
                 if t then return (acc.(x:)) else return acc
import-Control.Monad
{-
foldM::(单子m)=>(b->a->MB)->b->[a]->MB
filterM::(Monad m)=>(a->m Bool)->[a]->m[a]
-}
filtM::(单子m)=>(a->m布尔)->[a]->m[a]
filtM p xs=foldM f id xs>>=(返回($[]))
哪里

f acc x=do t是
myFilter p[]=[]
冗余?@БММЙМААЛцББССССB--是的,绝对是。注意
foldl
是这里的“错误”折叠,而
foldr
是“正确”折叠。例如,对于无限列表,
myFilter
|
,而原始的
filter
不是(好吧,假设谓词至少包含一个元素)。@MatveyAksenov yep,冗余的
反向
实际上是一个很好的症状,
foldl
使用错误。@Aksenov。据我所知,
Control.Monad
中没有
foldrM
。欢迎您提供您自己的实现(无需使用
反向
)作为答案,以及用
foldrM
表示
filterM
的代码。感谢您的回答。代码中的执行顺序有一个小问题,不知道为什么。这里有一个简单的测试。filterM(const[True,False])[1,2]=>[1,2],[1],[2],[2]。myFilterM(const[True,False])[1,2]=>[1,2],[2],[1],[]这是因为
反向
。啊!现在我明白了。我必须
liftM反转
myfilterM
的结果,而不是反转
l
,以获得标准执行顺序。现在一切都清楚了。