Haskell编译器如何处理'where'语句?

ned*_*ned 3 compiler-construction haskell ghc

在下面的函数中,我想知道编译器是否足够聪明,可以x保持不变,还是计算列表中每个项目的列表头部?(我正在使用GHC)

allSame :: Eq a => [a] -> Bool 
allSame xs = all (==x) xs  where x = head xs
Run Code Online (Sandbox Code Playgroud)

Don*_*art 11

GHC中"where"的语义是单个闭包将被分配给'x'并在所有用途中共享.将生成一个新的闭包,用于函数(=='x'),优化器将浮出它,这样它每次遍历只生成一次.

要准确查看生成的代码,请检查Core(例如,通过ghc-core).GHC优化代码:

M.allSame a eq xs =
    all
      (let 
         ds =
           case xs of 
             []   -> error "bad head"
             x : _-> x
            in
          \y -> x == y
         ) xs
Run Code Online (Sandbox Code Playgroud)

如果考虑性能,请考虑使用向量,因为单独的遍历将融合,从而消除递归.