GHC 6.8.1 SpecConstr

kenny lu haskellmail at gmail.com
Thu Nov 15 01:48:32 EST 2007


Hi,

Recall the example from Simon's paper appearing in ICFP 2007.

myLast :: [a] -> a
myLast [] = error ""
myLast [x] = x
myLast (x:xs) = myLast xs

which returns the last element in a list.

Applying the idea in the paper, we should rewrite the function
as follows,

myLast :: [a] -> a
myLast [] = error ""
myLast (x:xs) = myLast' x xs
    where myLast' x [] = x
          myLast' x (y:ys) = myLast' y ys

which avoids redundant pattern tests.


We tried to compile the "unspecialized" version of myLast function
with GHC 6.8.1
with -O2 -ddump-simpl flags and observe the core code as follows,

==================== Tidy Core ====================
lvl_r72 :: forall a_a5P. a_a5P
[GlobalId]
[Str: DmdType b]
lvl_r72 = \ (@ a_a5P) -> GHC.Err.error @ a_a5P (GHC.Base.[] @ GHC.Base.Char)

Rec {
Last.$smyLast :: forall a_a5P. a_a5P -> [a_a5P] -> a_a5P
[GlobalId]
[Arity 2]
Last.$smyLast =
  \ (@ a_a5P) (ipv_s6i :: a_a5P) (ipv1_s6j :: [a_a5P]) ->
    case ipv1_s6j of wild_X9 {
      [] -> ipv_s6i; : ipv2_X6p ipv3_X6r -> Last.myLast @ a_a5P wild_X9
    }
Last.myLast :: forall a_a5B. [a_a5B] -> a_a5B
[GlobalId]
[Arity 1
 Str: DmdType S]
Last.myLast =
  \ (@ a_a5P) (ds_d68 :: [a_a5P]) ->
    case ds_d68 of wild_B1 {
      [] -> lvl_r72 @ a_a5P;
      : x_a5I ds1_d69 ->
	case ds1_d69 of wild1_X9 {
	  [] -> x_a5I; : ipv_s6i ipv1_s6j -> Last.myLast @ a_a5P wild1_X9
	}
    }
end Rec }




==================== Tidy Core Rules ====================
"SC:Last.myLast0" [0]
    forall {@ a_a5P ipv_s6i :: a_a5P ipv1_s6j :: [a_a5P]}
      Last.myLast @ a_a5P (GHC.Base.: @ a_a5P ipv_s6i ipv1_s6j)
      = Last.$smyLast @ a_a5P ipv_s6i ipv1_s6j

It seems that $smyLast is the specialized version of myLast
And the last tidy core rule says that we should replace the
application  (myLast (x:xs))
by  ($smyLast x xs).

We are surprised by the development of the second pattern of $smyLast.
In the second pattern, function myLast is applied to wild_X9 which is
the reference of
ipv_s6j.

However, according to the running example,
it seems to make more sense if this application is
replaced by a recursive application ($smyLast ipv_3X6r) instead.

Could you guys please enlighten me?

Regards,
Kenny


More information about the Glasgow-haskell-users mailing list