Haskell - 延迟评估是不是会导致此文件夹停止评估所有功能
Posted
技术标签:
【中文标题】Haskell - 延迟评估是不是会导致此文件夹停止评估所有功能【英文标题】:Haskell - Will lazy evaluation cause this foldr to stop evaulating all functionsHaskell - 延迟评估是否会导致此文件夹停止评估所有功能 【发布时间】:2020-01-23 00:37:50 【问题描述】:func1, func2.. 都定义了 :: [String]-> Bool
一旦第一个 true 被命中,下面的折叠是否会停止评估函数
foldr (\x acc -> acc || x ) False ( fmap ($ "111") [func1,func2, func3, func4])
想一想,我意识到 fmap 将评估所有 4 个函数,然后将 [Bool] 传递给折叠......一旦它达到 True 就应该停止折叠。
我想我需要问的问题是,是否有办法将 fmap 合并到折叠中,以便在其中一个函数返回 true 时立即停止评估。
【问题讨论】:
您说“想一想我意识到 fmap 将评估所有 4 个函数,然后将 [Bool] 传递给折叠......一旦它达到 True 就应该停止折叠”。这是不真实的。仅仅因为它将[Bool]
传递给折叠,not 就意味着函数已被评估。他们会在需要时进行评估:如果您逐步完成纸上的评估,您可以自己了解何时发生这种情况。
【参考方案1】:
像你这样的功能
foldr (\x acc -> acc || x) False
已经为你写好了。它位于名称or
下的标准库中。请注意,它将参数的顺序翻转为(||)
,这是您想要的短路所必需的。因此,您可以将问题简化为
or . map ($ "111") $ fs
令人高兴的是,将函数映射到列表和or
-ing 其结果的想法非常普遍也:见证any
。所以我们可以将你的整个表达式重写为
any ($ "111") fs
这样我们就不必担心细节了:写any
的人小心翼翼地没有对列表进行不必要的评估,所以从您的角度来看,这是一个已解决的问题。
【讨论】:
不,这不是or
,因为它对||
的参数是错误的。【参考方案2】:
您的foldr
函数使用了错误的||
。你可能是想写:
foldr (\x acc -> x || acc) False
一旦你做出改变,不,不是所有的功能都会被评估。您可以通过Debug.Trace
亲自查看
main = print $ foldr (\x acc -> x || acc) False (fmap ($ True) [id, not, traceShowId, not])
这将只打印一个True
,表明列表中的第三个函数不是强制的。
【讨论】:
以上是关于Haskell - 延迟评估是不是会导致此文件夹停止评估所有功能的主要内容,如果未能解决你的问题,请参考以下文章