* Playing around, learning the basics, reinventing the wheel... I had been playing around with some classes, primarily to learn for myself, being new to the Haskell language, when I got the report on the current status of Haskell 1.3. The classes I had played with had some similarities to some of the proposals for the new prelude, yet I had made it in a quite different way. Trying to combine the two styles, I ran into an unexpected problem. This problem I am naive enough to believe could be solved by a simple language extension. Using Gofer, I had made some classes that could be used for implementing ordering and other things for enumeration (data T=T1 | T2 | T3) types but not restricted to those. I made 4 minimal classes with just 1 function in each. (I thought this would be most general. Something having a minimum value, in my view, didn't necessarily imply it would have a maximum value.) So: class FromInt a where fromInt:: Int->a class ToInt a where toInt:: a->Int class MaxVal a where maxVal:: a class MinVal a where minVal:: a -- I then used this as follows: data T = T1 | T2 | T3 instance ToInt T where toInt e = case e of T1 -> 1 T2 -> 2 T3 -> 3 instance Eq T where a == b = toInt a == toInt b instance Ord T where a <= b = toInt a <= toInt b -- And so on. The MaxVal and MinVal classes also where used to make a generic -- implementation of a bounded Enum class, generalizing how it was made in the -- Gofer prelude for Char: instance (FromInt a, ToInt a, MinVal a, MaxVal a) => Enum a where enumFrom c = map fromInt [toInt c .. toInt (maxVal `asTypeOf` c)] enumFromThen c c' = map fromInt [toInt c, toInt c' .. toInt (lastVal `asTypeOf` c)] where lastVal = if c' < c then minVal else maxVal -- This worked to my great delight! And I had began to learn the basics -- of the type system in Haskell. My only problem was that I had to use -- (maxVal `asTypeOf` c) instead of (maxVal::a). I believe the reason -- for this might be clear when I learn more. Somebody have a clue? * Running into a problem: type class synonyms are not synonymous? Then, I got the report on the developments of Haskell 1.3 and began to read it with great curiosity. I then found the Bounded class, containing corresponding functions to MinVal and MaxVal. A question then occured to me: Why not have separate classes as I had done? Would not that perhaps be more general, increasing the possibilities for reuse? (Without having to stub out one of minBound or maxBound if you use it for a type without one of them.) On the other hand, I saw the convenience of having both minBound and maxBound in the same class, decreasing the number of classes that have to be mentioned in various cases. But I thought, then, why not derive the Bounded class >from MinVal and MaxVal - would not that then be equivalent? So I tried class (MinVal a, MaxVal a)=>Bounded a -- This was allowed, but then... instance Bounded T where maxVal = T3 minVal = T1 -- That didn't work! (Gofer said: ERROR "tst.gs" (line 45): No member "maxVal" in class "Bounded") Maybe I had done something wrong, or Gofer does not allow something that would be allowed in Haskell? I suspect however that I am simply not supposed to do this in either Haskell or Gofer... Instead I had to use two separate instantiaions, exactly as before I declared the Bounded class: instance MinVal T where minVal = T1 instance MaxVal T where maxVal = T3 This seems to be somewhat unnecessary, wouldn't it be quite possible for a compiler to transform the instantiation of Bounded to the two instantiations of MinVal and MaxVal? Maybe this would be a useful development of Haskell? * Should Bounded be derived from Ord? The Bounded class that was suggested for Haskell 1.3 was derived from Ord. Myself playing with similar things I derived MinVal and MaxVal >from nothing - I thought this more general. Maybe the reason for having Bounded derived from Ord was to imply that its functions shall satisfy certain laws, probably as being min/max as defined by the ordering functions in Ord. But as I don't see how this can be guaranteed by deriving Bounded from Ord, I would think that it could as well be standalone (or derived from something like MinBound and MaxBound if possible); for more generality and less dependency between the classes in the system. For example, the new proposal says: > ... > Programmers are free to define a class for partial orderings; here, we > simply state that Ord is reserved for total orderings. That seems to imply also that a programmer should not use Bounded on types that have no total ordering. I believe this might be an unnecessary restriction. * Can toInt be fromEnum and toEnum fromInt? New functions fromEnum and toEnum were proposed to be added to Haskell 1.3 prelude as follows: > * Replace the functions ord and chr with the functions: > > fromEnum :: (Bounded a, Enum a) => a -> Int > fromEnum x = diff x (minBound x) > > toEnum :: (Bounded a, Enum a) => Int -> a > toEnum x = succ (minBound x) x It was further mentioned in Notes that: > The names fromEnum and toEnum are misleading since > their types involve both Enum and Bounded. We couldn't face writing > fromBoundedEnum and toBoundedEnum. Suggestions > welcome. Maybe names like ToInt and FromInt could be used for this? How about the following, assuming the proposed diff and succ functions: instance (Bounded a, Enum a) => ToInt a where toInt x = diff x (minBound x) instance (Bounded a, Enum a) => FromInt a where fromInt x = succ (minBound x) x --- I would be very interested and grateful for any comments on these and related subjects. (Please try to be polite about my ignorance, though, if possible...) Sverker Nilsson ------------------------------- S. Nilsson Computer System AB Ekholmsv. 28B S-582 61 LINKOPING