haskell - 列表理解中的表达式是否被冗余评估?

标签 haskell optimization functional-programming list-comprehension ghc

let strings = ["foo", "bar", "baz"]
in  [filter (== char) (concat strings) | char <- "oa"]

GHC 是否在 char == 'o' 时评估 concat strings,然后在 char == 'a' 时再次评估?或者它是否记得 concat strings == "foobarbaz" 供以后使用?

我意识到我可以通过重构这段代码来避免这种不确定性,但我对代码的编译方式很感兴趣。

最佳答案

GHC 对其进行评估的次数可能远少于 9 次。事实上它确实如此,我们可以证明使用 Debug.Trace.trace

module Main (main) where 
import Debug.Trace

x = let strings = ["foo", "bar", "baz"]
    in  [filter (== char) (trace "\nconcat strings\n" (concat strings)) | char <- "oaxyz"]

main = do
    print x

这是对“oaxyz”进行 5 次 -O0 计算,一次 -O1 和 -O2 计算:

! 529)-> touch LC.hs ; ghc -O0 -o lc0 LC.hs 
[1 of 1] Compiling Main             ( LC.hs, LC.o )
Linking lc0 ...

(! 530)-> touch LC.hs ; ghc -O1 -o lc1 LC.hs 
[1 of 1] Compiling Main             ( LC.hs, LC.o )
Linking lc1 ...

(! 531)-> ./lc0; ./lc1; ./lc2

concat strings


concat strings


concat strings


concat strings


concat strings

["oo","aa","","","z"]

concat strings

["oo","aa","","","z"]

concat strings

["oo","aa","","","z"]

关于haskell - 列表理解中的表达式是否被冗余评估?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20309507/

相关文章:

clojure - 当原始函数被绑定(bind)隐藏时如何调用它?

haskell - 上传包到hackages时没有生成haddock

haskell - 列表理解和类型问题 (Haskell)

haskell - 如何将多态函数应用于 Either 的两边?

c# - JIT简单优化

python - 比 python 中的嵌套循环更快的搜索方式

haskell - 我很困惑为什么这种合并排序的实现不起作用?

c++ - 映射/折叠运算符(在 C++ 中)

haskell - GHC 8.4 系列的插件名称查找行为发生变化

java - 我如何修改此代码使其时间复杂度为 o(log n) 或 o(n) 而不是 o(n^2)