Haskell有折叠吗?

Jef*_*ges 9 monads haskell fold

如何严格折叠monad? Data.Foldable有严格foldl'和一元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
Run Code Online (Sandbox Code Playgroud)

我也许可以使用Maybemonad来略微简化这段代码,foldlM但这样做看似缺乏必要的严格性.

ehi*_*ird 10

没有这样的标准功能,但很容易定义:

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
Run Code Online (Sandbox Code Playgroud)

这只是标准foldM,但与之相同seq(与之foldl'相比foldl).它可能没有在任何标准中定义,因为它不太可能是有用的:对于大多数monad来说,(>>=)在某种意义上你需要使用左折叠而不会溢出堆栈是"严格的"; 这只有当你的过多的thunk在返回的值本身时才有用,但是一个有用的应用程序foldM将使用最后一步的值执行一些monadic计算,这使得这不太可能.

我认为你的代码很简单; 我怀疑foldM'会不会更优雅.

  • @JeffBurdges - 这是一种特殊的观察,其中Monadic` >> =`严格与懒惰:http://stackoverflow.com/a/8250334/208257 (3认同)