This page is no longer maintained — Please continue to the home page at www.scala-lang.org

Generic Implicit Converters?

4 replies
wagnereu
Joined: 2009-01-09,
User offline. Last seen 3 years 40 weeks ago.

Hi everybody,

I'm wondering whether it's possible to make a generic implicit converter. I'll try to explain what I mean.

First I wrote a normal implicit converter to make java.util.Date appear like Ordered[Date]

import java.util.Date
implicit def dateOrderer(d: Date) =
new Ordered[Date] {
def compare(that: Date) = {
d.compareTo(that)
}
}

I noticed that the code could be reused for any Java type that supports interface Comparable by replacing "Date" with the type in question.

So I tried to make the code generic but the compiler didn't like it. Here's what I tried:

implicit def comparableToOrdered[T](d: Comparable[T]) =
new Ordered[Comparable[T]] {
def compare (that: Comparable[T]) = {
d.compareTo(that)
}
}

Is there a way to code such a thing so that it compiles (and runs) ;o)?

cheers
Eugene Wagner

Remarque concernant la sécurité:
Ce courriel provenant de PostFinance est signé. Vous trouverez d'autres informations à ce sujet sous:
https://www.postfinance.ch/e-signature.
Ne divulguez jamais vos éléments de sécurité à des tiers.

David Flemström
Joined: 2009-08-10,
User offline. Last seen 42 years 45 weeks ago.
Re: Generic Implicit Converters?
On Sat, Sep 11, 2010 at 12:39 PM, <eugene [dot] wagner [at] postfinance [dot] ch> wrote:
So I tried to make the code generic but the compiler didn't like it.  Here's what I tried:

 implicit def comparableToOrdered[T](d: Comparable[T]) =
   new Ordered[Comparable[T]] {
     def compare (that: Comparable[T]) = {
       d.compareTo(that)
     }
   }

Is there a way to code such a thing so that it compiles (and runs) ;o)?
Yes.
The problem with your code is that you're giving too much work to the compiler for it to handle. You're saying "For any type T, if there exists a Comparable[T], implicitly convert it to Ordered[Comparable[T]]". So you basically force the compiler to check every type it knows of to see if the type it is trying to convert is a Comparable[T] for that type T.
(Which wouldn't be a problem if a human was to solve the problem, but a compiler can't use "common sense" etc. and just bails out)
What you instead want to say: "For any type A that extends Comparable[A], implicitly convert it to Ordered[A]", or:
implicit def comparableToOrdered[A <: Comparable[A]](comparable: A): Ordered[A] =
  new Ordered[A] {
    def compare(a: A) = comparable.compare(a)
  }

David Flemström
Joined: 2009-08-10,
User offline. Last seen 42 years 45 weeks ago.
Re: Generic Implicit Converters?


On Sat, Sep 11, 2010 at 12:50 PM, David Flemström <david [dot] flemstrom [at] gmail [dot] com> wrote:
On Sat, Sep 11, 2010 at 12:39 PM, <eugene [dot] wagner [at] postfinance [dot] ch> wrote:
So I tried to make the code generic but the compiler didn't like it.  Here's what I tried:

 implicit def comparableToOrdered[T](d: Comparable[T]) =
   new Ordered[Comparable[T]] {
     def compare (that: Comparable[T]) = {
       d.compareTo(that)
     }
   }

Is there a way to code such a thing so that it compiles (and runs) ;o)?
Yes.
The problem with your code is that you're giving too much work to the compiler for it to handle. You're saying "For any type T, if there exists a Comparable[T], implicitly convert it to Ordered[Comparable[T]]". So you basically force the compiler to check every type it knows of to see if the type it is trying to convert is a Comparable[T] for that type T.
(Which wouldn't be a problem if a human was to solve the problem, but a compiler can't use "common sense" etc. and just bails out)
What you instead want to say: "For any type A that extends Comparable[A], implicitly convert it to Ordered[A]", or:
implicit def comparableToOrdered[A <: Comparable[A]](comparable: A): Ordered[A] =
  new Ordered[A] {
    def compare(a: A) = comparable.compare(a)
  }
Correction: The implementation of "compare" should of course be "comparable.compareTo(a)"
wagnereu
Joined: 2009-01-09,
User offline. Last seen 3 years 40 weeks ago.
RE: Generic Implicit Converters?

David,

 

Wow, it works.  Thanks a bunch!

 

Thanks for the explanation too.  You touched on something that I wasn't aware of.  I'm still trying to digest it actually :o)

 

cheers

Eugene

 

From: David Flemström [mailto:david [dot] flemstrom [at] gmail [dot] com]
Sent: Samstag, 11. September 2010 12:53
To: Wagner Eugene, PF51
Cc: scala [at] listes [dot] epfl [dot] ch
Subject: Re: [scala] Generic Implicit Converters?

 

 

On Sat, Sep 11, 2010 at 12:50 PM, David Flemström <david [dot] flemstrom [at] gmail [dot] com> wrote:

On Sat, Sep 11, 2010 at 12:39 PM, <eugene [dot] wagner [at] postfinance [dot] ch> wrote:

So I tried to make the code generic but the compiler didn't like it.  Here's what I tried:

 implicit def comparableToOrdered[T](d: Comparable[T]) =
   new Ordered[Comparable[T]] {
     def compare (that: Comparable[T]) = {
       d.compareTo(that)
     }
   }

Is there a way to code such a thing so that it compiles (and runs) ;o)?

Yes.

 

The problem with your code is that you're giving too much work to the compiler for it to handle. You're saying "For any type T, if there exists a Comparable[T], implicitly convert it to Ordered[Comparable[T]]". So you basically force the compiler to check every type it knows of to see if the type it is trying to convert is a Comparable[T] for that type T.

 

(Which wouldn't be a problem if a human was to solve the problem, but a compiler can't use "common sense" etc. and just bails out)

 

What you instead want to say: "For any type A that extends Comparable[A], implicitly convert it to Ordered[A]", or:

 
implicit def comparableToOrdered[A <: Comparable[A]](comparable: A): Ordered[A] =
  new Ordered[A] {
    def compare(a: A) = comparable.compare(a)
  }

Correction: The implementation of "compare" should of course be "comparable.compareTo(a)"



Remarque concernant la sécurité:
Ce courriel provenant de PostFinance est signé. Vous trouverez d'autres informations à ce sujet sous:
https://www.postfinance.ch/e-signature.
Ne divulguez jamais vos éléments de sécurité à des tiers.
Randall R Schulz
Joined: 2008-12-16,
User offline. Last seen 1 year 29 weeks ago.
Re: Generic Implicit Converters?

On Saturday September 11 2010, David Flemström wrote:
> ...
>
> What you instead want to say: "For any type A that extends
> Comparable[A], implicitly convert it to Ordered[A]", or:
>
> implicit def comparableToOrdered[A <: Comparable[A]](comparable: A):
> Ordered[A] =
> new Ordered[A] {
> def compare(a: A) = comparable.compare(a)
> }

Be aware that to use this in practice would cause an object creation for
every comparison to be performed. Used, e.g., when sorting and for
simple comparisons could add significantly to the total time required.
Ordering is better than Ordered from this perspective, so if you can do
this in the Comparator -> Ordering realm, you might be better off.

Randall Schulz

Copyright © 2012 École Polytechnique Fédérale de Lausanne (EPFL), Lausanne, Switzerland