- About Scala
- Documentation
- Code Examples
- Software
- Scala Developers
Java generics in Scala
Sat, 2009-03-07, 05:46
I have these two Java classes
class Unit>
class Measurement>
What could be their equivalent in Scala?
This does not work:
class Unit[U <: Unit[U]]
class Measurement[U <: Unit[_ >: U]] //compile error: illegal cyclic
reference involving type U
What is the right way of achieving this?
Sat, 2009-03-07, 13:47
#2
Re: Re: Java generics in Scala
O/H Eric Willigers έγραψε:
> If above definition of UnitC should not be permitted,
> change definition of Unit to
> class Unit[U <: Unit[U]] { this: U => }
Unless I'm missing something, isn't this exactly equivalent to the
following?
class Unit { this: U => }
U is the self-type of Unit, and of course always U <: Unit. I don't see
anything gained by the additional type parameter.
Most probably, the intent of the following Java declaration:
class Unit>
was to define U as the Unit's self type, which is directly supported in
scala.
Sat, 2009-03-07, 14:47
#3
Re: Re: Java generics in Scala
Unless I'm missing something, isn't this exactly equivalent to the following?
class Unit { this: U => }
U is the self-type of Unit, and of course always U <: Unit. I don't see anything gained by the additional type parameter.
It is not.
First of all
class Unit { this: U => }
will not compile as it is, since U is not known at the time of declaration of Unit.
Also have a look at:
trait Irrelevantobject TheIrrelevant extends Irrelevant
trait Unit { this: Irrelevant => }
The above compiles fine and Irrelevant is perfectly independent of Unit, as proven by the creation of TheIrrelevant.
Most probably, the intent of the following Java declaration:
class Unit<U extends Unit<U>>
was to define U as the Unit's self type, which is directly supported in scala.
This is called an F-bound. In the field of type-parameterization of a class, abstract type members and self-types are two more alternatives, loosely speaking. You could take a look at the "Scalable Component Abstractions" paper.
Christos
--
__~O
-\ <, Christos KK Loverdos
(*)/ (*) http://ckkloverdos.com
Sat, 2009-03-07, 15:27
#4
Re: Re: Java generics in Scala
Right, thanks. I thought that "this: U =>" would make U the type of
this, but that's simply "this.type" or "U => ", and in any case it's not
the self type (but the type with a single value, this), and is only
useful (as far as I can see) in method chaining, so indeed the "extra"
type parameter is most probably necessary.
O/H Christos KK Loverdos έγραψε:
>
> Unless I'm missing something, isn't this exactly equivalent to the
> following?
> class Unit { this: U => }
>
> U is the self-type of Unit, and of course always U <: Unit. I
> don't see anything gained by the additional type parameter.
>
>
> It is not.
>
> First of all
>
> class Unit { this: U => }
>
> will not compile as it is, since U is not known at the time of
> declaration of Unit.
>
> Also have a look at:
>
> trait Irrelevant
> object TheIrrelevant extends Irrelevant
> trait Unit { this: Irrelevant => }
>
> The above compiles fine and Irrelevant is perfectly independent of
> Unit, as proven by the creation of TheIrrelevant.
>
>
>
>
> Most probably, the intent of the following Java declaration:
>
> class Unit>
>
> was to define U as the Unit's self type, which is directly
> supported in scala.
>
>
>
> This is called an F-bound. In the field of type-parameterization of a
> class, abstract type members and self-types are two more alternatives,
> loosely speaking. You could take a look at the "Scalable Component
> Abstractions" paper.
>
> Christos
>
Mushtaq Ahmed wrote:
> I have these two Java classes
>
> class Unit>
> class Measurement>
>
> What could be their equivalent in Scala?
>
> This does not work:
>
> class Unit[U <: Unit[U]]
> class Measurement[U <: Unit[_ >: U]] //compile error: illegal cyclic
> reference involving type U
>
> What is the right way of achieving this?
Here's one approach with Scala 2.7.3:
class Unit[U <: Unit[U]]
class Measurement[T <: Unit[T], U <: T]
class UnitA extends Unit[UnitA]
class UnitB extends UnitA
class UnitC extends Unit[UnitA]
class MeasurementA extends Measurement[UnitA, UnitA]
class MeasurementB extends Measurement[UnitA, UnitB]
If above definition of UnitC should not be permitted,
change definition of Unit to
class Unit[U <: Unit[U]] { this: U => }