#7542: GHC doesn't optimize (strict) composition with id ------------------------------------+--------------------------------------- Reporter: shachaf | Owner: Type: bug | Status: new Priority: normal | Component: Compiler Version: 7.6.1 | Keywords: Os: Unknown/Multiple | Architecture: Unknown/Multiple Failure: Runtime performance bug | Blockedby: Blocking: | Related: ------------------------------------+--------------------------------------- Newtype constructors and selectors have no runtime overhead, but some uses of them do. For example, given `newtype Identity a = Identity { runIdentity :: a }`, `Identity` turns into `id`, but `Identity . f` turns into `id . f`, which is distinct from `f`, because it gets eta-expanded to `\x -> f x`.
It would be nice to be able to compose a newtype constructor with a function without any overhead. The obvious thing to try is strict composition: {{{ (#) :: (b -> c) -> (a -> b) -> a -> c (#) f g = f `seq` g `seq` \x -> f (g x) }}} In theory this should get rid of the eta-expansion. In practice, the generated Core looks like this: {{{ foo :: (a -> b) -> [a] -> [b] foo f = map (id # f) -- becomes foo = \f e -> map (case f of g { __DEFAULT -> \x -> g x }) e }}} Different variations of `(#)`, and turning `-fpedantic-bottoms` on, don't seem to affect this. A simpler version, `foo f = map (f `seq` \x -> f x)`, generates the same sort of Core. In one library we resorted to defining a bunch of functions of the form `identityDot :: (a -> b) -> a -> Identity b; identityDot = unsafeCoerce`. It would be better to be able to rely on GHC to do the optimization directly, if we use strict composition anyway. -- Ticket URL: <http://hackage.haskell.org/trac/ghc/ticket/7542> GHC <http://www.haskell.org/ghc/> The Glasgow Haskell Compiler _______________________________________________ Glasgow-haskell-bugs mailing list Glasgow-haskell-bugs@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs