haskellghc

How does the Haskell compiler handle the 'where' statement?


In the following function, I'm wondering if the compiler is clever enough to work out that x is going to remain constant, or will it compute the head of the list for every item in the list? (I'm using GHC)

allSame :: Eq a => [a] -> Bool 
allSame xs = all (==x) xs  where x = head xs

Solution

  • The semantics of 'where' in GHC is that a single closure will be allocated for 'x' and shared amongst all uses. A new closure, for the function (== 'x') will be generated, and the optimizer will float it out, so that it is only generated once per traversal.

    To see exactly what code is generated, check the Core (e.g. via ghc-core). GHC optimizes the code to:

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

    If performance is a concern, consider using vectors, as the separate traversals will fuse, removing recursion.