unexpected arithmetic sequence and deriving Enum behaviour

Laszlo Nemeth lnemeth at cs.bilgi.edu.tr
Fri Jun 30 09:05:31 EDT 2006


Hi,

Consider the following code fragment:

data Colour = Red | Black | Blue deriving (Show, Bounded)

instance Enum Colour where
    succ Red   = Black
    succ Black = Blue
    succ Blue  = error "succ of maxBound"

    fromEnum Red   = 1
    fromEnum Black = 2
    fromEnum Blue  = 3

    toEnum 1 = Red
    toEnum 2 = Black
    toEnum 3 = Blue
    toEnum n = error ("? "++show n)

main = do print $ [Red ..]

Notice that there is no deriving Enum (which would be an error according 
to the Report) and there is no definition for 'enumFrom'.

So, in the first place I'd expect a warning for main for the use of the 
arithmetic sequence, something about a missing definition. There isn't 
one, and the program compiles. Interestingly, -ddump-deriv doesn't show 
anything about deriving instances for  Colour, yet, obviously something 
gets derived.

When you run it, it dies with an error message from 'toEnum n' (or 
non-exhaustive pattern if you leave that one out). Looking at core  
reveals the reason for this:

Main.lvl7 :: GHC.Base.Int -> [Main.Colour] -> [Main.Colour]
[GlobalId]
[Arity 2]
Main.lvl7 = \ (x1 :: GHC.Base.Int) (ys :: [Main.Colour]) ->
              GHC.Base.: @ Main.Colour (Main.toEnum x1) ys

Main.lvl8 :: [Main.Colour]
[GlobalId]
[]
Main.lvl8 = GHC.Enum.eftIntFB
              @ [Main.Colour] Main.lvl7 (GHC.Base.[] @ Main.Colour) 1 
2147483647

Main.lvl9 :: [Main.Colour]
[GlobalId]
[]
Main.lvl9 = GHC.Enum.eftIntFB
              @ [Main.Colour] Main.lvl7 (GHC.Base.[] @ Main.Colour) 2 
2147483647

Main.lvl10 :: [Main.Colour]
[GlobalId]
[]
Main.lvl10 = GHC.Enum.eftIntFB
               @ [Main.Colour] Main.lvl7 (GHC.Base.[] @ Main.Colour) 3 
2147483647

Main.$dmenumFrom :: Main.Colour -> [Main.Colour]
[GlobalId]
[Arity 1
 Str: DmdType S]
Main.$dmenumFrom = \ (w :: Main.Colour) ->
                     case [Main.Colour] w of wild {
                       Main.Red -> Main.lvl8; Main.Black -> Main.lvl9; 
Main.Blue -> Main.lvl10
                     }

The max bound which gets used is the one for Int, not for Colour!

Perhaps this isn't a bug, but definitely an undocumented and rather 
unexpected 'feature'. This is with ghc-6.4  onwards, and I haven't 
checked earlier versions.

Share and enjoy.
  Laszlo



More information about the Glasgow-haskell-bugs mailing list