On Fri, 23 Oct 1998, Ralf Hinze wrote:

 | If local instance declarations were admissable I could possibly write
 | ... lots of hand-waving ...
 | 
 | > sortBy (rel :: Rel a)      =  sort where instance Ord a where (<=) = rel

Look at Mondrian:

  http://www.cs.chalmers.se/~koen/Papers/mondrian.ps

The intention there was that this would be easy to do. Dictonaries are
implemented by records (possibly containing polymorphic functions):

  class Ord a where
  { (<=) :: a -> a -> Bool
  }

defines a record type containing one field: <=.

If we want to compare two elements, we can explicitly choose a Ord-record:

  intOrd :: Ord Int
  intOrd = Ord{ (<=) = primIntCompare }

  1 intOrd.<= 2 :: Bool

Or we can leave it implicit:

  1 <= 2 :: Ord Int => Bool

Note that the type expresses that we haven't specified an ordering yet.

Implementing a sorting function, is like adding an extra selector function
to the Ord record. It goes like this:

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

Now, if we want to use sort on different orderings:

  sort [1,2,3,4]          :: Ord Int => [Int]
  intOrd.sort [1,2,3,4]   :: [Int]
  crazyOrd.sort [1,2,3,4] :: [Int]
  ...

We can also implement a function that flips a sorting:

  rev :: Ord a -> Ord a
  rev ord = Ord{ (<=) = flip (ord.<=) }

Note that this is defined as a record transformer, rather than as a new
selector function for Ord. And now we can define "revsort", using the
flipped ordering:

  revsort :: Ord a => [a] -> [a]
  ord.revsort = (rev ord).sort

I really like these ideas, and the paper has a few more examples.
Unfortunately there seem to be some semantic issues wrong with it (what to
do if you have multiple record in your contexts).

Regards,
Koen.

--
Koen Claessen,
[EMAIL PROTECTED],
http://www.cs.chalmers.se/~koen,
Chalmers University of Technology.


Reply via email to