Mon, 17 Apr 2000 10:07:51 -0400, Chris Okasaki <[EMAIL PROTECTED]> pisze: > Many of you have run across the problem with newtypes that, although > it is very cheap to coerce between the newtype and the base type, it > can be very expensive to coerce between, say, a list of the newtype > and a list of the base type. Stephanie Weirich and I are working > on a proposal for the Haskell Workshop addressing this problem, > and we would welcome any feedback from the community. Fo me it looks like it requires introducing more special rules to the language than it's worth it. I don't think that the problem of converting complex structures of newtypes is so common to justify introducing not so pretty rules to the language. GHC has the RULES pragma and unsafeCoerce#, which can be used in a particular case when the performance is so critical and the compiler is unable to optimize the conversion itself. Instead, I think that the following extension would be more useful. When we use newtype to create a new numeric type, we must make instances of various classes ourselves. The deriving mechamism saves us from boring Eq and Ord instances, but will not help with Num or Integral even if they are "obvious". Proposal. Allow specifying any single-parameter type class in the deriving list of a newtype, provided that method types agree with the following rules, the type under the newtype is an instance of that class, and the newtype is an instance of all superclasses. Each method is derived from the corresponding method for the oldtype. Implementation is easier than specification of exact rules :-) The intent is that the same physical code will work for the newtype as well. To obtain this, the implementation of the method is formally converted, as driven by old and new types of the method. An expression e of type t is converted to C[e] thus: - If t does not mention the oldtype, the target type is the same and C[e] = e. - If t is the oldtype, then C[e] = N e, where N is the newtype's constructor. - If t is a function type, then C[e] = e `seq` \x -> C[e (C'[x])], where C' is the dual conversion, from the new type to the old type. - If t is a tuple type, then C[e] = case e of (e1,...,eN) -> (C[e1],...,C[eN]). This is needed e.g. for Integral's quotRem. - If t is the list type, then C[e] = map (\x -> C[x]) e. This is needed e.g. for Enum's enumFromTo. - Otherwise the class is not derivable. So it works for all Prelude type classes. The only conflict with current derivings is for Show and Read, which is unfortunate because it's not obvious which case is needed and I'm not sure how to resolve it. -- __("< Marcin Kowalczyk * [EMAIL PROTECTED] http://qrczak.ids.net.pl/ \__/ GCS/M d- s+:-- a23 C+++$ UL++>++++$ P+++ L++>++++$ E- ^^ W++ N+++ o? K? w(---) O? M- V? PS-- PE++ Y? PGP+ t QRCZAK 5? X- R tv-- b+>++ DI D- G+ e>++++ h! r--%>++ y-