可以根据fold
函数定义许多高阶函数。例如,这是Haskell中filter
和foldl
之间的关系。
myFilter p [] = []
myFilter p l = foldl (\y x -> if (p x) then (x:y) else y) [] (reverse l)
他们的monadic版本filterM
和foldM
之间是否存在类似的关系?如何以filterM
?
foldM
我努力寻找等同于\y x -> if (p x) then (x:y) else y
的monadic来插入foldM
但没有成功。
答案 0 :(得分:2)
就像D.M。的回答一样,只有reverse
。让类型指导您:
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
答案 1 :(得分:1)
不确定它是否有任何意义(因为它有奇怪的reverse
),但至少它的类型检查得很好:
myFilterM :: Monad m => (a -> m Bool) -> [a] -> m [a]
myFilterM p l = foldM f [] (reverse l)
where
f y x = do
p1 <- p x
return $ if p1 then (x:y) else y