Hi Koen, | If Show were not a super class of Num, the following program | would generate an error: | | main = print 42 | | If Eq were not a super class, the following program would | not work: | | main = print (if 42 == 42 then "koe" else "apa") | | These programs are all fixed by inserting Show and Eq as | super classes of Num. So that one does not even notice! Your claims are incorrect. Both of these examples type check without any errors, and regardless of whether Show and Eq are included as superclasses of Num. It is easy to verify this using "Typing Haskell in Haskell" (http://www.cse.ogi.edu/~mpj/thih); I'll attach the script that I used for this below. Put this in the same directory as all the other .hs files and load it into Hugs. Then edit StdPrel.hs to remove the superclasses of cNum, (replace [cEq, cShow] with []), and it will still work. | For years I have wondered why the Num class has the Eq class | and the Show class as super classes. | | Because of this, I cannot make functions an instance of Num | (because they are not in Eq or Show). Or a datatype | representing an infinite amount of digits (because Eq would | not make any sense). | | Now I have found out the reason! I don't think you have. I do not know the reason either, but I suspect that it is largely historical; when Haskell was first designed, the only types that people wanted to put in Num were also equality and showable types. By making Eq and Show superclasses of Num, types could sometimes be stated more concisely, writing things like (Num a) => ... instead of (Num a, Eq a, Show a) => ... In the past ten years since the Haskell class hierarchy was, more or less, fixed, we've seen several examples of types that don't quite fit (Like functions, computable reals, etc. which might make sense in Num but not in Eq). A natural conclusion is that several of the superclass relations between classes should be removed. But realize that there is an unavoidable compromise here: generality versus the convenience of shorter types. I suggest that there is no point on the spectrum that would keep everybody happy all the time. | It is of the defaulting mechanism of course! | ... Defaulting is a red herring in trying to understand why Show and Eq are superclasses of Num. Marcin has already pointed out that your description of the Haskell defaulting mechanism is not correct by quoting from the Haskell report. You can find another description, again based on the report, in the thih paper. | So I define a type class: | class Num a => Number a where | convertToDouble :: a -> Double | convertFromDouble :: Double -> a |... | All my library functions now have the shape: | libraryFunction :: Number a => ... a ... | ... | And now the bad thing... When I use "libraryFunction" on a | numeric constant, such as 42, I get the error: | | ERROR "library.hs" (line 8): Unresolved overloading | *** Binding : main | *** Outstanding context : Number b | | So here are my questions. Why does the default mechanism | have this restriction? I know that the default mechanism is | already broken (some desirable properties are destroyed) -- | what properties will be broken by lifting this restriction? Defaulting only kicks in if (a) at least one class is numeric, and (b) all classes are standard. Number is not a standard class (you just defined it yourself), so defaulting will not apply. Defaulting was designed to work in this way so that (i) it would catch and deal with the most common problems occurring with numeric literals, and (ii) it would not be used too often; defaulting is in general undesirable because it can silently change the semantics. Again, defaulting is an example of a compromise in the design of Haskell. Ideally, you'd do without it all together, but if you went that way, you'd end up having to write more type information in your programs. And again, I don't suppose there is a universally satisfactory point on this spectrum. All the best, Mark ---------------------------------------------------------------------------- [EMAIL PROTECTED] Pacific Software Research Center, Oregon Graduate Institute Want to do a PhD or PostDoc? Interested in joining PacSoft? Let us know!
module SourceFortyTwo where import Testbed import HaskellPrims import HaskellPrelude ----------------------------------------------------------------------------- -- Test Framework: main :: IO () main = test imports fortyTwo saveList :: IO () saveList = save "FortyTwo" imports fortyTwo imports :: [Assump] imports = defnsHaskellPrims ++ defnsHaskellPrelude ----------------------------------------------------------------------------- -- Test Program: fortyTwo :: [BindGroup] fortyTwo = map toBg [[("main", Nothing, [([], ap [evar "print", elit (LitInt 42)])])], [("main'", Nothing, [([], ap [evar "print", eif (ap [econst eqMfun, elit (LitInt 42), elit (LitInt 42)]) (elit (LitStr "koe")) (elit (LitStr "apa"))])])]] -----------------------------------------------------------------------------