简体   繁体   English

Haskell有折叠吗?

[英]Does Haskell have foldlM'?

How does one fold over a monad strictly? 如何严格折叠monad? Data.Foldable has the strict foldl' and the monadic foldlM , but no strict foldlM' ? Data.Foldable具有严格的foldl'foldlM ,但没有严格的foldlM' Is the strictness somehow defined by the monad itself? 严格是由monad本身定义的吗? If so, how does one work out what it is? 如果是这样,一个人如何解决它是什么?

Imagine I must determine whether the product of an enormous list of ring elements is zero, but my ring isn't an integral domain, ie it contains zero devisors. 想象一下,我必须确定一个巨大的环元素列表的产品是否为零,但我的环不是一个完整的域,即它包含零设计。 In this case, I should tail recursively foldl my multiplication *** over the list, but return False the moment the product becomes zero, rather than waiting on the full product. 在这种情况下,我应该在列表中递归地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

I could perhaps simplify this code slightly using the Maybe monad's foldlM but doing so seemingly lacks the required strictness. 我也许可以使用Maybe monad的foldlM稍微简化这段代码,但这样做似乎缺乏必要的严格性。

There's no such standard function, but it's easy to define: 没有这样的标准功能,但很容易定义:

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

This is just the standard foldM , but with the same seq ing in it that foldl' does (compared to foldl ). 这仅仅是标准的foldM ,但具有相同的seq荷兰国际集团在认为foldl'不(相比foldl )。 It's probably not defined anywhere standard because it's not likely to be all that useful: for most monads, (>>=) is "strict" in the sense you need to use a left-fold without overflowing the stack; 它可能没有在任何标准定义,因为它不太可能是有用的:对于大多数monad, (>>=)是“严格”的,你需要使用左折叠而不会溢出堆栈; this is only useful when your excessive thunks are in the returned values themselves, but a useful application of foldM will perform some monadic computation with the value from the last step, making that unlikely. 这只有当你的过多的thunk在返回的值本身时才有用,但是foldM一个有用的应用程序将使用上一步的值执行一些foldM计算,这使得这不太可能。

I think your code is simple enough as it is; 我认为你的代码很简单; I doubt foldM' would make it any more elegant. 我怀疑foldM'会让它变得更优雅。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM