haskell - Haskell 有 foldlM' 吗?

标签 haskell monads fold

一个人如何严格地折叠一个单子(monad)? Data.Foldable 有严格的foldl'和单子(monad)foldlM , 但没有严格的 foldlM' ?单子(monad)本身是否以某种方式定义了严格性?如果是这样,如何确定它是什么?

想象一下,我必须确定一个庞大的环元素列表的乘积是否为零,但我的环不是一个整数域,即它包含零除数。在这种情况下,我应该递归地拖尾 foldl我的乘法***在列表中,但返回 False产品变为零的那一刻,而不是等待完整的产品。

safelist :: [p] -> Bool
safelist [] = True
safelist (x:xs) = snd $ foldl' f (x,True) xs
   where  f (u,b) v = (w, b && w /= Zero)  where  w = u *** v

我或许可以使用 Maybe 稍微简化此代码monad 的 foldlM但这样做似乎缺乏所需的严格性。

最佳答案

没有这样的标准函数,但很容易定义:

foldM' :: (Monad m) => (a -> b -> m a) -> a -> [b] -> m a
foldM' _ z [] = return z
foldM' f z (x:xs) = do
  z' <- f z x
  z' `seq` foldM' f z' xs

这只是标准 foldM ,但使用相同的 seq在里面说foldl'确实(与 foldl 相比)。它可能没有在任何标准中定义,因为它不太可能很有用:对于大多数 monad,(>>=)在您需要使用左折叠而不溢出堆栈的意义上是“严格的”;这仅在返回值本身包含过多的 thunk 时才有用,但是 foldM 的有用应用将使用最后一步的值执行一些单子(monad)计算,这不太可能。

我认为您的代码很简单;我怀疑 foldM'会让它更优雅。

关于haskell - Haskell 有 foldlM' 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8919026/

相关文章:

haskell - 以foldr 来定义scanr 是如何工作的?

haskell - 如何使用秒差距解析一行?

haskell - 在 Haskell 中执行 UTF-8 的简单库(因为 Streams 不再编译)

list - 通过分布 [] 来简化代码

haskell - unsafeVacous、#. 和 .# 何时不安全?

Haskell 的 foldr/foldl 定义绊倒新手?对于 foldl 实际函数采用 f(默认情况)x 而对于 foldr 函数采用 f x(默认情况)?

haskell - Haskell 有 `foldr` 的急切版本吗?

haskell - 为复杂类型创建任意实例

haskell - 为什么我不能将其从 Monad 推广到 Applicative?

haskell - Haskell 中的并行 monad 映射?像 parMapM 之类的东西?