|
View:
New views
7 Messages
—
Rating Filter:
Alert me
|
|
|
parametric types and varianceHi all,
can anyone explain to me why the following code compiles? As I understand it, Aa acts as the lower bound in the implementation of classify in class AaClassifier and so I wonder why I'm able to pass in a String. Cheers Christoph object Test { def main(args: Array[String]) { println(new AaClassifier().classify("a")) } } trait Classifier[+T] { def classify[U >: T](t: U): String } class AaClassifier extends Classifier[Aa] { def classify[T >: Aa](t: T) = t.toString } class Aa |
|
|
Re: parametric types and varianceOn Thu, Jul 9, 2009 at 3:23 PM, Christoph Drießen<ced@...> wrote:
> can anyone explain to me why the following code compiles? As I understand > it, Aa acts as the lower bound in the implementation of classify in class > AaClassifier and so I wonder why I'm able to pass in a String. You've got your bounds the wrong way around: that's an upper bound, so T can be instantiated to the supertypes of Aa which are Any, AnyRef etc. What I think you want is, trait Classifier[+T] { def classify[U <: T](t: U): String } class AaClassifier extends Classifier[Aa] { def classify[T <: Aa](t: T) = t.toString } Cheers, Miles -- Miles Sabin tel: +44 (0)7813 944 528 skype: milessabin http://www.chuusai.com/ http://twitter.com/milessabin |
|
|
Re: parametric types and varianceHi Miles,
page 396 of Programming in Scala says: " U >: T defines T as the lower bound for U". So U must be a supertype of T. In that way you're right and that's how I understand it. But how is it possible to pass in a String? String isn't a supertype of Aa. The change you've suggested does not compile: covariant type T occurs in contravariant position in type >: scala.this.Nothing <: T of type U&0 def classify[U <: T](t: U): String Cheers, Christoph Am 09.07.2009 um 16:31 schrieb Miles Sabin: > On Thu, Jul 9, 2009 at 3:23 PM, Christoph Drießen<ced@...> wrote: >> can anyone explain to me why the following code compiles? As I >> understand >> it, Aa acts as the lower bound in the implementation of classify in >> class >> AaClassifier and so I wonder why I'm able to pass in a String. > > You've got your bounds the wrong way around: that's an upper bound, so > T can be instantiated to the supertypes of Aa which are Any, AnyRef > etc. > > What I think you want is, > > trait Classifier[+T] { > def classify[U <: T](t: U): String > } > > class AaClassifier extends Classifier[Aa] { > def classify[T <: Aa](t: T) = t.toString > } > > Cheers, > > > Miles > > -- > Miles Sabin > tel: +44 (0)7813 944 528 > skype: milessabin > http://www.chuusai.com/ > http://twitter.com/milessabin > |
|
|
Re: parametric types and varianceOk, got it! Thanks Miles!
But Classifier also needs to be contravariant it T. I assume you just forgot to change + to - Miles, right? trait Classifier[-T] { def classify[U <: T](t: U): String } Am 09.07.2009 um 18:20 schrieb Christoph Drießen: > Hi Miles, > page 396 of Programming in Scala says: " U >: T defines T as the > lower bound for U". So U must be a supertype of T. In that way > you're right and that's how I understand it. But how is it possible > to pass in a String? String isn't a supertype of Aa. > > The change you've suggested does not compile: > covariant type T occurs in contravariant position in type >: > scala.this.Nothing <: T of type U&0 > def classify[U <: T](t: U): String > > Cheers, > Christoph > > > > Am 09.07.2009 um 16:31 schrieb Miles Sabin: > >> On Thu, Jul 9, 2009 at 3:23 PM, Christoph Drießen<ced@...> wrote: >>> can anyone explain to me why the following code compiles? As I >>> understand >>> it, Aa acts as the lower bound in the implementation of classify >>> in class >>> AaClassifier and so I wonder why I'm able to pass in a String. >> >> You've got your bounds the wrong way around: that's an upper bound, >> so >> T can be instantiated to the supertypes of Aa which are Any, AnyRef >> etc. >> >> What I think you want is, >> >> trait Classifier[+T] { >> def classify[U <: T](t: U): String >> } >> >> class AaClassifier extends Classifier[Aa] { >> def classify[T <: Aa](t: T) = t.toString >> } >> >> Cheers, >> >> >> Miles >> >> -- >> Miles Sabin >> tel: +44 (0)7813 944 528 >> skype: milessabin >> http://www.chuusai.com/ >> http://twitter.com/milessabin >> > |
|
|
Re: parametric types and varianceI recommend reading the Chapter about variance of Programming in Scala.
Anyway, notice that what varies is the type ACCEPTED by classify. In this case, classify[AnyRef] is both a supertype of Aa, thus respecting the lower bound, and of String, so a String can be passed to it.
If that is confusing, imagine you defined classify to be:
def classify(t: AnyRef) = t.toString
Can you pass a String to such a method? Of course you can, because a String is a subtype of AnyRef. You can pass pretty much anything, except Java primitive types (Scala's AnyVal). Since AnyRef is a supertype of AA, then this is a valid definition for classify.
On Thu, Jul 9, 2009 at 1:20 PM, Christoph Drießen <ced@...> wrote: Hi Miles, -- Daniel C. Sobral Something I learned in academia: there are three kinds of academic reviews: review by name, review by reference and review by value. |
|
|
Re: parametric types and varianceOn Thu, Jul 09, 2009 at 04:23:40PM +0200, Christoph Drießen wrote:
> can anyone explain to me why the following code compiles? As I > understand it, Aa acts as the lower bound in the implementation of > classify in class AaClassifier and so I wonder why I'm able to pass in > a String. Because you're not passing a String, you're passing an AnyRef (which happens to be a String.) -- Paul Phillips | One way is to make it so simple that there are Moral Alien | obviously no deficiencies. And the other way is to make Empiricist | it so complicated that there are no obvious deficiencies. up hill, pi pals! | -- Hoare |
|
|
|
| Free embeddable forum powered by Nabble | Forum Help |