在下面的函数中,我想知道编译器是否足够聪明来计算出 x
将保持不变,还是会为列表中的每个项目计算列表的头部? (我正在使用 GHC)
allSame :: Eq a => [a] -> Bool
allSame xs = all (==x) xs where x = head xs
最佳答案
GHC 中“where”的语义是为“x”分配一个闭包并在所有用途之间共享。将为函数 (== 'x') 生成一个新的闭包,优化器会将其浮出,以便每次遍历仅生成一次。
要准确查看生成的代码,请检查核心(例如通过 ghc-core)。 GHC 将代码优化为:
M.allSame a eq xs =
all
(let
ds =
case xs of
[] -> error "bad head"
x : _-> x
in
\y -> x == y
) xs
如果性能是一个问题,请考虑使用向量,因为单独的遍历将融合,从而消除递归。
关于compiler-construction - Haskell 编译器如何处理 'where' 语句?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3581381/