[prev in list] [next in list] [prev in thread] [next in thread] 

List:       haskell
Subject:    Re: ordering classes
From:       mareb () cis0 ! levels ! unisa ! edu ! au (Bob Buckley)
Date:       1994-03-02 0:58:21
Message-ID: 9403020058.AA20980 () animal ! cs ! chalmers ! se
[Download RAW message or body]

Resent-Message-Id: <9403020058.AA20980@animal.cs.chalmers.se>
From: mareb@cis0.levels.unisa.edu.au (Bob Buckley)
Subject: Re: ordering classes
Date: Wed, 02 Mar 1994 11:07:41 -0600 (CST)
To: haskell@dcs.gla.ac.uk
Old-Resent-From: haskell-request@dcs.gla.ac.uk
Errors-To: haskell-request@dcs.gla.ac.uk
Approved: haskell@dcs.gla.ac.uk
Resent-Date:  Wed, 2 Mar 1994 00:41:33 +0000
Resent-From: kh
Resent-To: haskell-list-dist


In reply to jhf@lanl.gov:

One difference between my proposal and yours is that my proposal
narrows the prelude rather than extending it. With my proposal,
you can construct much of what you want though you can't reuse
the method names as you might like.

An interesting question has to do with how to implement mathematical
generalisations. The implementation you suggest is via:

class General a => Specific a where ...

This allows specific methods to reuse the names of the general methods.
As a result, when the properties of a more specific class are required in
a function though only the methods defined in a general class are used,
and explicit type declaration should be used, hence a sorting function using
only (<=) might need to be declared:

sort :: Ord a => [a] -> [a]
sort xs = ...

since the type system would infer that the type is:

sort :: PreOrd a => [a] -> [a]

The mechanism I used was:

class Specific a where ...
class General  a where ...

instance Specific a => General a where generalOp = specificOp ...

e.g. instance Ord a => Eq a where x==y = x<=y && y<=x

This requires different names for the methods, so the name space
might get quite poluted/complex. It does allow the following mechanisms:

instance Specific2 a => General a where ...
instance General a => General2 a where ...

which appears to be a more flexible since it allows arbitrary
generalisation. But this is not the way O-O programming is done and
it is not consistent with the existing prelude(s).

This is a matter of style, really.

Another style issue concerns which methods to include in a class.
I'm not sure we have this right at the moment either.

At present, class Eq a has (==) and (/=) methods. The default
implementation for (/=) expresses what I would hope is a LAW. By
taking (/=) out of the class, the user is prevented from (perhaps
erroneously) redefining this in an instance. Perhaps the user should be
forced to use non-standard SPECIALISE mechanisms to achieve this result.

Perhaps this produces some supporting arguments for the above view
of classes. For a total ordering, we expect:

   x<y = y>x = not( y<=x ) = x<=y&&x/=y = x<=y&&not(y<=x)

For a partial ordering we only expect:

   x<y = y>x = x<=y&&x/=y = x<=y&&not(y<=x)

For efficiency, I expect we'd prefer to base an implementation around:

 x<y = not(y<=x)

With a different method name, the partial ordering needs a new implementation:

 x<?y = x<=?y&&not(y<=?x)

both of which can be defined as laws (i.e. outside the class). Further,
the following instance might be useful:

   instance PartialOrd a => Eq a where x==y = x<=?y && y<=?x

Done this way, both Ord and Eq can be in the prelude, yet the user can
slip PartialOrd into an application or a library between them. This style
appears more flexible than the more popular `inheritance' style. I'm not
sure what efficiency issues this raises or whether a complicated namespace
is worth the flexibility.

	regards
	b++
_______________________________________________________________________
Bob Buckley					Phone: +61 8 302 3465
School of Computer and Information Science	Fax:   +61 8 302 3381
University of South Australia, The Levels,
Pooraka, SA 5095, Australia		email: Bob.Buckley@UniSA.edu.au



[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic