haskell - 常数空间短路`foldM`超过`Maybe`
问题描述
可以说我有以下内容:
f :: b -> a -> b
x :: b
l :: [a]
和
foldl' f x l
在恒定空间中运行。那f
是适当的严格。
现在考虑我是否有:
f2 :: b -> a -> Maybe b
f2 x y = if (pred x y) then Just $! (f x y) else Nothing
将要
foldM f2 x l
在恒定空间中可靠地运行?或者我还需要做些什么来确保我有恒定的空间但仍然有短路行为Maybe
?
(请注意,虽然我问过这个问题Maybe
,但我实际上想用 来做这个Either
,但我怀疑方法是相似的)
解决方案
在库源代码foldM
中定义为foldlM
,而后者又定义为
foldlM :: (Foldable t, Monad m) => (b -> a -> m b) -> b -> t a -> m b
foldlM f z0 xs = foldr c return xs z0
where c x k z = f z x >>= k
假设 ,c x k z = f2 z x >>= k
让我们看看当我们调用它时会发生什么。要查看它是否是常量空间,我们将仅通过应用最顶层的函数来减少表达式,而不减少子表达式。
foldlM f2 z0 (x:xs)
=
foldr c return (x:xs) z0
=
c x (foldr c return xs) z0
=
f2 z0 x >>= foldr c return xs
由于>>=
对第一个参数严格,我们f2 z0 x
首先评估。如果返回Nothing
,我们将忽略其余部分(如您提到的短路)。如果返回Just y
,我们有
Just y >>= foldr c return xs
=
foldr c return xs y
我们已经为下一个循环做好了准备。
这并没有导致我们的术语增长,所以它看起来像是在恒定空间中运行(当然,前提f2
是保持恒定的大小y
)。
推荐阅读
- reactjs - 无法在渲染进程 Electron 上连接到 NeDB
- reactjs - 在 React 中使用 Httponly Cookie 持久化用户会话
- python - 无论如何要更改带有数据框表的绘图中的 xticks 吗?
- c# - 如何在上传时调整图像大小以减小图像大小?
- json - Dart json序列化,如何处理来自mongodb的_id在Dart中是私有的?
- javascript - 是否可以在移动视图上同时进行水平滚动并显示所有(具有切换效果)
- github - GitHub 的 GPG 公钥是什么?
- java-native-interface - JNI 调用 MIP SDK 给出错误 - 无法打开数据库,检查文件夹权限:mip_data\mip\mip.policies.sqlite3
- java - 安卓图标不见了
- java - 在线程数有限的多个线程中读取文件