Haskell 哈斯凯尔有折叠式';?
一个人如何严格地折叠单子?有严格的Haskell 哈斯凯尔有折叠式';?,haskell,monads,fold,Haskell,Monads,Fold,一个人如何严格地折叠单子?有严格的foldl'和一元的foldlM,但没有严格的foldlM'?严格是由单子本身定义的吗?如果是这样的话,人们如何计算出它是什么 想象一下,我必须确定一个庞大的环元素列表的乘积是否为零,但我的环不是一个整型域,也就是说,它包含零个除法器。在这种情况下,我应该在列表上递归地执行foldl我的乘法***,但在乘积变为零时返回False,而不是等待完整的乘积 safelist :: [p] -> Bool safelist [] = True safelist (
foldl'
和一元的foldlM
,但没有严格的foldlM'
?严格是由单子本身定义的吗?如果是这样的话,人们如何计算出它是什么
想象一下,我必须确定一个庞大的环元素列表的乘积是否为零,但我的环不是一个整型域,也就是说,它包含零个除法器。在这种情况下,我应该在列表上递归地执行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
我也许可以使用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':(Monad m)=>(a->b->ma)->a->[b]->ma
foldM'z[]=返回z
foldM'fz(x:xs)=do
z'>=)
是“严格”的,因为您需要使用左折叠而不会溢出堆栈;这仅在返回值本身包含过多的thunk时才有用,但是foldM
的有用应用程序将使用上一步的值执行一些单元计算,这就不太可能了
我认为你的代码已经足够简单了;我怀疑
foldM'
会使它变得更优雅。啊,我想如果monad中有严格的标志,它可以使事情变得严格,但不是这样。没有标准的单子能做到这一点。谢谢@JeffBurdges——这里有一个特别的观察,一元>=
是严格的还是懒惰的:事实上,如果你的(>>=)
太懒,我怀疑foldM'
会有帮助,因为例如,强制惰性状态返回一个值并不一定强制状态。