Hello!

On Fri, Oct 23, 1998 at 01:44:58PM +0200, Johannes Waldmann wrote:
> > Your thought would destroy equational reasoning! For example you
> > would be able to define different equalties on the same data
> > structure. So Red==Black could be False in one place and True 
> > in another place. Does that make any sense? 

> well, yes and no, of course :-) 

> for instance, i could want to sort a list,
> according to two different criteria,
> using two different instances of Ord.

newtype IntFunnilyOrdered = IFO Int
instance Ord IntFunnilyOrdered where
  compare (IFO x) (IFO y) | even x && even y = compare x y
                          | even x && odd y  = LT
                          | odd x && even y  = GT
                          | otherwise        = compare x y
int_from_ifo (IFO x) = x

newtype IntReverse = IR Int
instance Ord IntReverse where
  compare (IR x) (IR y) = compare y x
int_from_ir (IR x) = x

Now, you can do
  map int_from_ir $ sort $ map IR l
or
  map int_from_ifo $ sort $ map IFO l

Ideally, the compiler should figure out that map IFO and map
int_from_ifo are essentially noops, except changing the class
instances to use.

Or use a function sortWith :: (a -> a -> Ordering) -> [a] -> [a]
and give it the ordering to use as parameter.

> moreover, i would need these instances only while sorting,
> so i would like to keep them local.

If you use the instances once, I think using something like sortWith
instead will be more elegant.

> [...]

> i fear there are more problems hidden. let's take this:

> data T = ...

> xx = let instance Ord T where ...
>            x :: T = ...
>      in  x

> yy = let instance Ord T where ...
>           y :: T = ...
>      in y

> do xx and yy have the same type? yes and no, again,
> it looks like they belong to different (incomparable) subtypes of T.

> what about the expression (xx < yy)? which instance to use?
> none - on the outside it's not visible that T is any Ord instance, 
> so you cannot compare them at all.

Hmmm. So in your sorting example:

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

foo = let instance Ord T where compare ... = ... in sort (something::[T])

There's no Ord instance visible in the definition of sort.

And if you dynamically assign those instances and transport them to
sort, this becomes a real mind twist:

sort :: ... (as above)

somelist :: [T]
somelist = let instance Ord T where ... in (generate some list of values in T)

sortedlist :: [T]
sortedlist = let instance Ord T where [different from the above instance] in
  sort somelist

Now, which instance to usw? That bound to the values when they were
generated, i.e. that local to somelist? Or is that instance replaced by
that in sortedlist by that let instance binding?

That somehow twists my mind :-)

Regards, Felix.


Reply via email to