Skip to content

map has strange unfolding, code blowup and performance loss

module Test where
f xs = map (True:) xs

gives this with ghc-6.8.1 -O -ddump-simpl:

==================== Tidy Core ====================
Rec {
Test.go :: [[GHC.Base.Bool]] -> [[GHC.Base.Bool]]
[GlobalId]
[Arity 1
 NoCafRefs
 Str: DmdType S]
Test.go =
  \ (ds_a6S :: [[GHC.Base.Bool]]) ->
    case ds_a6S of wild_a6T {
      [] -> GHC.Base.[] @ [GHC.Base.Bool];
      : y_a6X ys_a6Y ->
        GHC.Base.:
          @ [GHC.Base.Bool]
          (GHC.Base.: @ GHC.Base.Bool GHC.Base.True y_a6X)
          (Test.go ys_a6Y)
    }
end Rec }

Test.f :: [[GHC.Base.Bool]] -> [[GHC.Base.Bool]]
[GlobalId]
[Arity 1
 NoCafRefs
 Str: DmdType S]
Test.f =
  \ (xs_a5B :: [[GHC.Base.Bool]]) ->
    case xs_a5B of wild_a5Q {
      [] -> GHC.Base.[] @ [GHC.Base.Bool];
      : x_a5T xs1_a5U ->
        GHC.Base.:
          @ [GHC.Base.Bool]
          (GHC.Base.: @ GHC.Base.Bool GHC.Base.True x_a5T)
          (Test.go xs1_a5U)
    }

This is not, as I first suspected, that the mapList rule is not firing - the RULEs are firing as they should. The problem is that map itself has this unfolding:

map :: forall a b. (a -> b) -> [a] -> [b]
  {- Arity: 2 HasNoCafRefs Strictness: LS
     Unfolding: (\ @ a @ b ds :: a -> b ds1 :: [a] ->
                 case @ [b] ds1 of wild {
                   [] -> GHC.Base.[] @ b
                   : x xs
                   -> GHC.Base.:
                        @ b
                        (ds x)
                        (GHC.Base.foldr
                           @ a
                           @ [b]
                           (\ x1 :: a ys :: [b] -> GHC.Base.: @ b (ds x1) ys)
                           (GHC.Base.[] @ b)
                           xs) }) -}

Highly strange - map's unfolding refers to foldr, but map itself is written with the usual recursive definition in GHC.Base. The only explanation I can think of is that the RULEs for map must have applied in map's definition when GHC.Base was compiled.

This is bad, because of the code blowup and also because performance will be badly affected for non-optimised compilation (map is defined in terms of foldr).

Trac metadata
Trac field Value
Version 6.6.1
Type Bug
TypeOfFailure OtherFailure
Priority normal
Resolution Unresolved
Component Compiler
Test case
Differential revisions
BlockedBy
Related
Blocking
CC
Operating system Unknown
Architecture Unknown
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information