RE: unexpected arithmetic sequence and deriving Enum behaviour

2006-07-03 Thread Simon Peyton-Jones
| one, and the program compiles. Interestingly, -ddump-deriv doesn't
show
| anything about deriving instances for  Colour, yet, obviously
something
| gets derived.

For me (ghc 6.4.2) it says:
 Derived instances 
InstInfo: {GHC.Show.Show Foo4.Colour}
  { GHC.Show.showList = GHC.Show.showList__ (GHC.Show.showsPrec 0)
GHC.Show.showsPrec (_) (Foo4.Red) = GHC.Show.showString Red
GHC.Show.showsPrec (_) (Foo4.Black) = GHC.Show.showString Black
GHC.Show.showsPrec (_) (Foo4.Blue) = GHC.Show.showString Blue }
InstInfo: {GHC.Enum.Bounded Foo4.Colour}
  { GHC.Enum.maxBound = Foo4.Blue
GHC.Enum.minBound = Foo4.Red }

Not very pretty, but definitely not nothing.

| When you run it, it dies with an error message from 'toEnum n' (or
| non-exhaustive pattern if you leave that one out).

That's exactly as specified by the Report. If you look here, 
http://haskell.org/onlinereport/standard-prelude.html
and search for class Enum, you'll se

class  Enum a  where
   ..[snip]...
-- NOTE: these default methods only make sense for types
--   that map injectively into Int using fromEnum
--  and toEnum.
enumFrom x   =  map toEnum [fromEnum x ..]

and this is precisely the behaviour you get.

I agree it isn't the behaviour your want.  If every Enum was Bounded,
the enumFrom default method could stop at maxBound.  But Enum and
Bounded are separate classes.

Simon


___
Glasgow-haskell-bugs mailing list
Glasgow-haskell-bugs@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs


unexpected arithmetic sequence and deriving Enum behaviour

2006-06-30 Thread Laszlo Nemeth

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
___
Glasgow-haskell-bugs mailing list
Glasgow-haskell-bugs@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs


Re: unexpected arithmetic sequence and deriving Enum behaviour

2006-06-30 Thread Simon Marlow

Hi Laszlo,

Laszlo Nemeth wrote:


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)


Why do you say that?  Can you give a pointer to the relevant text in the 
report?  I can't see anything wrong here.


The minimal complete instance of Enum consists of toEnum and fromEnum, 
which yours does.


 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:



[ core snipped ]


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


This is because, as per the report, GHC defines the default method for 
enumFrom as:


enumFrom x = map toEnum [fromEnum x ..]

the sequence on the RHS is at type Int, and hence doesn't terminate 
until it reaches maxBound::Int.



Perhaps you expect that, because your type is also an instance of 
Bounded, that enumFrom should behave differently.  However, there can 
only be one default method for enumFrom.


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.


You're right, I don't think it's a bug.  Also, if you had derived Enum 
instead of defining it, you would have got a version that behaved in the 
expected way.  You defined an instance of Enum yourself, and got 
exactly what you asked for!


Cheers,
Simon
___
Glasgow-haskell-bugs mailing list
Glasgow-haskell-bugs@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs


Re: unexpected arithmetic sequence and deriving Enum behaviour

2006-06-30 Thread Stefan Holdermans

Simon,

Laszlo presented some code:


Consider the following code fragment:
data Colour = Red | Black | Blue deriving (Show, Bounded)
instance Enum Colour where


...

and then remarked:

Notice that there is no deriving Enum (which would be an error  
according to the Report)


You asked:

Why do you say that?  Can you give a pointer to the relevant text  
in the report?  I can't see anything wrong here.


I think he was referring to the fact that it is illegal to both  
*derive* and *define* an instance of a particular class for a type.


Regards,

  Stefan
___
Glasgow-haskell-bugs mailing list
Glasgow-haskell-bugs@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs