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

Cyclic reference?

14 replies
David Pollak
Joined: 2008-12-16,
User offline. Last seen 42 years 45 weeks ago.
Howdy,
If I've got a trait that takes its implementor as a parameter:
trait AboutMe[A <: AboutMe[A]] {
  self: A =>
}

I can create a class that extends the trait:
class Test extends AboutMe[Test] // works

But I can't seem to create an object that extends the trait without going through the intermediate step of creating a class and making the object an instance of the class.
object T2 extends AboutMe[T2] // fails
object T2 extends AboutMe[T2.type] // fails

Any advice would be appreciated.
Thanks,
David
--
Lift, the simply functional web framework http://liftweb.net
Beginning Scala http://www.apress.com/book/view/1430219890
Follow me: http://twitter.com/dpp
Git some: http://github.com/dpp
marius
Joined: 2008-08-31,
User offline. Last seen 3 years 19 weeks ago.
Re: Cyclic reference?
I might be way off ... but

object T2 is not a Type.

Br's,
Marius

On Wed, Feb 11, 2009 at 10:55 PM, David Pollak <feeder [dot] of [dot] the [dot] bears [at] gmail [dot] com> wrote:
Howdy,
If I've got a trait that takes its implementor as a parameter:
trait AboutMe[A <: AboutMe[A]] {
  self: A =>
}

I can create a class that extends the trait:
class Test extends AboutMe[Test] // works

But I can't seem to create an object that extends the trait without going through the intermediate step of creating a class and making the object an instance of the class.
object T2 extends AboutMe[T2] // fails
object T2 extends AboutMe[T2.type] // fails

Any advice would be appreciated.
Thanks,
David
--
Lift, the simply functional web framework http://liftweb.net
Beginning Scala http://www.apress.com/book/view/1430219890
Follow me: http://twitter.com/dpp
Git some: http://github.com/dpp

David Pollak
Joined: 2008-12-16,
User offline. Last seen 42 years 45 weeks ago.
Re: Cyclic reference?


On Wed, Feb 11, 2009 at 1:32 PM, Marius Danciu <marius [dot] danciu [at] gmail [dot] com> wrote:
I might be way off ... but

object T2 is not a Type.

But T2.type should be a type.
 


Br's,
Marius

On Wed, Feb 11, 2009 at 10:55 PM, David Pollak <feeder [dot] of [dot] the [dot] bears [at] gmail [dot] com> wrote:
Howdy,
If I've got a trait that takes its implementor as a parameter:
trait AboutMe[A <: AboutMe[A]] {
  self: A =>
}

I can create a class that extends the trait:
class Test extends AboutMe[Test] // works

But I can't seem to create an object that extends the trait without going through the intermediate step of creating a class and making the object an instance of the class.
object T2 extends AboutMe[T2] // fails
object T2 extends AboutMe[T2.type] // fails

Any advice would be appreciated.
Thanks,
David
--
Lift, the simply functional web framework http://liftweb.net
Beginning Scala http://www.apress.com/book/view/1430219890
Follow me: http://twitter.com/dpp
Git some: http://github.com/dpp




--
Lift, the simply functional web framework http://liftweb.net
Beginning Scala http://www.apress.com/book/view/1430219890
Follow me: http://twitter.com/dpp
Git some: http://github.com/dpp
Jorge Ortiz
Joined: 2008-12-16,
User offline. Last seen 29 weeks 3 days ago.
Re: Cyclic reference?
This bit of code led me to discover several... unfortunate... aspects of the type system.

1)

Class types can be used as parameters to types the class extends, but singleton types can't be used as parameters to types the singleton extends.

trait Param[T]
class Test1 extends Param[Test1]    // works
object Test2 extends Param[Test2.type]    // fails

2)

Parametrized types can be used as self types, but abstract types can't.

trait Self1[T] { self: T => }    // works
trait Self2 { self:T => type T }    // fails

3)

Parametrized types can have cyclic references, but abstract types can't.

trait Param[T]
trait Abs { type T }
trait Cyclic1[A <: Param[A]]    // works
trait Cyclic2[A <: Abs { type T = A }]    // fails
trait Cyclic3 { type A <: Abs { type T = A } }    // fails
trait Cyclic4 { type A <: Param[A] }   // works



Are these as intended or can I file tickets on them?

--j

On Wed, Feb 11, 2009 at 12:55 PM, David Pollak <feeder [dot] of [dot] the [dot] bears [at] gmail [dot] com> wrote:
Howdy,
If I've got a trait that takes its implementor as a parameter:
trait AboutMe[A <: AboutMe[A]] {
  self: A =>
}

I can create a class that extends the trait:
class Test extends AboutMe[Test] // works

But I can't seem to create an object that extends the trait without going through the intermediate step of creating a class and making the object an instance of the class.
object T2 extends AboutMe[T2] // fails
object T2 extends AboutMe[T2.type] // fails

Any advice would be appreciated.
Thanks,
David
--
Lift, the simply functional web framework http://liftweb.net
Beginning Scala http://www.apress.com/book/view/1430219890
Follow me: http://twitter.com/dpp
Git some: http://github.com/dpp

Meredith Gregory
Joined: 2008-12-17,
User offline. Last seen 42 years 45 weeks ago.
Re: Cyclic reference?
Jorge,

i don't see an instance on here that doesn't seem sound. Almost all of these have to do with when the declaration introduces a level of indirection and when it doesn't. Your first example is paradigmatic. The class decl is introducing a new type that just happens to be recursively defined. The object decl is creating an instance of given type. The common use case of this declaration is to create an instance of a type that's already been defined. The case that's not covered can be covered by factoring into a decl of the first form followed by a standard object decl.

Best wishes,

--greg

On Thu, Feb 12, 2009 at 5:38 PM, Jorge Ortiz <jorge [dot] ortiz [at] gmail [dot] com> wrote:
This bit of code led me to discover several... unfortunate... aspects of the type system.

1)

Class types can be used as parameters to types the class extends, but singleton types can't be used as parameters to types the singleton extends.

trait Param[T]
class Test1 extends Param[Test1]    // works
object Test2 extends Param[Test2.type]    // fails

2)

Parametrized types can be used as self types, but abstract types can't.

trait Self1[T] { self: T => }    // works
trait Self2 { self:T => type T }    // fails

3)

Parametrized types can have cyclic references, but abstract types can't.

trait Param[T]
trait Abs { type T }
trait Cyclic1[A <: Param[A]]    // works
trait Cyclic2[A <: Abs { type T = A }]    // fails
trait Cyclic3 { type A <: Abs { type T = A } }    // fails
trait Cyclic4 { type A <: Param[A] }   // works



Are these as intended or can I file tickets on them?

--j

On Wed, Feb 11, 2009 at 12:55 PM, David Pollak <feeder [dot] of [dot] the [dot] bears [at] gmail [dot] com> wrote:
Howdy,
If I've got a trait that takes its implementor as a parameter:
trait AboutMe[A <: AboutMe[A]] {
  self: A =>
}

I can create a class that extends the trait:
class Test extends AboutMe[Test] // works

But I can't seem to create an object that extends the trait without going through the intermediate step of creating a class and making the object an instance of the class.
object T2 extends AboutMe[T2] // fails
object T2 extends AboutMe[T2.type] // fails

Any advice would be appreciated.
Thanks,
David
--
Lift, the simply functional web framework http://liftweb.net
Beginning Scala http://www.apress.com/book/view/1430219890
Follow me: http://twitter.com/dpp
Git some: http://github.com/dpp




--
L.G. Meredith
Managing Partner
Biosimilarity LLC
806 55th St NE
Seattle, WA 98105

+1 206.650.3740

http://biosimilarity.blogspot.com
Jorge Ortiz
Joined: 2008-12-16,
User offline. Last seen 29 weeks 3 days ago.
Re: Cyclic reference?
I agree that your interpretation is the one that most closely matches the language (spec and implementation). However, I can think of an alternate interpretation that intuitively makes sense. An object declaration introduces a new type, albeit one that can only have a single instance. (Hence objects are loaded lazily. Before they are accessed, the type exists but the instance does not.)

I'm not saying these things -should- be otherwise, but I can make an argument about why they might be and (given David's use case) it's clear that it might be useful if they were otherwise.

With (2) and (3), parametrized and abstract are so similar and almost interchangeable, that it'd be nice if their only differences were a matter of notation and convenience, rather than limits on what can be expressed with each.

For example, another snippet I forgot to mention:

2.5)

Types can't be initialized early.

trait Self3 extends { type T } with { self: T => } // fails

--j

On Thu, Feb 12, 2009 at 10:25 PM, Meredith Gregory <lgreg [dot] meredith [at] gmail [dot] com> wrote:
Jorge,

i don't see an instance on here that doesn't seem sound. Almost all of these have to do with when the declaration introduces a level of indirection and when it doesn't. Your first example is paradigmatic. The class decl is introducing a new type that just happens to be recursively defined. The object decl is creating an instance of given type. The common use case of this declaration is to create an instance of a type that's already been defined. The case that's not covered can be covered by factoring into a decl of the first form followed by a standard object decl.

Best wishes,

--greg

On Thu, Feb 12, 2009 at 5:38 PM, Jorge Ortiz <jorge [dot] ortiz [at] gmail [dot] com> wrote:
This bit of code led me to discover several... unfortunate... aspects of the type system.

1)

Class types can be used as parameters to types the class extends, but singleton types can't be used as parameters to types the singleton extends.

trait Param[T]
class Test1 extends Param[Test1]    // works
object Test2 extends Param[Test2.type]    // fails

2)

Parametrized types can be used as self types, but abstract types can't.

trait Self1[T] { self: T => }    // works
trait Self2 { self:T => type T }    // fails

3)

Parametrized types can have cyclic references, but abstract types can't.

trait Param[T]
trait Abs { type T }
trait Cyclic1[A <: Param[A]]    // works
trait Cyclic2[A <: Abs { type T = A }]    // fails
trait Cyclic3 { type A <: Abs { type T = A } }    // fails
trait Cyclic4 { type A <: Param[A] }   // works



Are these as intended or can I file tickets on them?

--j

On Wed, Feb 11, 2009 at 12:55 PM, David Pollak <feeder [dot] of [dot] the [dot] bears [at] gmail [dot] com> wrote:
Howdy,
If I've got a trait that takes its implementor as a parameter:
trait AboutMe[A <: AboutMe[A]] {
  self: A =>
}

I can create a class that extends the trait:
class Test extends AboutMe[Test] // works

But I can't seem to create an object that extends the trait without going through the intermediate step of creating a class and making the object an instance of the class.
object T2 extends AboutMe[T2] // fails
object T2 extends AboutMe[T2.type] // fails

Any advice would be appreciated.
Thanks,
David
--
Lift, the simply functional web framework http://liftweb.net
Beginning Scala http://www.apress.com/book/view/1430219890
Follow me: http://twitter.com/dpp
Git some: http://github.com/dpp




--
L.G. Meredith
Managing Partner
Biosimilarity LLC
806 55th St NE
Seattle, WA 98105

+1 206.650.3740

http://biosimilarity.blogspot.com

ewilligers
Joined: 2008-08-20,
User offline. Last seen 3 years 17 weeks ago.
Re: Cyclic reference?

Jorge Ortiz wrote:
> This bit of code led me to discover several... unfortunate... aspects of
> the type system.

> 2)
>
> Parametrized types can be used as self types, but abstract types can't.
>
> trait Self1[T] { self: T => } // works
> trait Self2 { self:T => type T } // fails

http://scala-webapps.epfl.ch/bugtracking/contribs/display.do?id=478

This was resolved such that the following works:

trait Self2 {
type T >: this.type

// "this" can be used as a T
}

I've been using it since 2.6.0

There's the occasional trap:
http://scala-webapps.epfl.ch/bugtracking/bugs/displayItem.do?id=1161

Jorge Ortiz
Joined: 2008-12-16,
User offline. Last seen 29 weeks 3 days ago.
Re: Re: Cyclic reference?
Cool!

Learn something new every day :)

--j

On Fri, Feb 13, 2009 at 1:46 AM, Eric Willigers <ewilligers [at] gmail [dot] com> wrote:
Jorge Ortiz wrote:
This bit of code led me to discover several... unfortunate... aspects of the type system.

2)

Parametrized types can be used as self types, but abstract types can't.

trait Self1[T] { self: T => }    // works
trait Self2 { self:T => type T }    // fails


http://scala-webapps.epfl.ch/bugtracking/contribs/display.do?id=478

This was resolved such that the following works:

trait Self2 {
   type T >: this.type

   // "this" can be used as a T
}



I've been using it since 2.6.0

There's the occasional trap:
http://scala-webapps.epfl.ch/bugtracking/bugs/displayItem.do?id=1161


Jorge Ortiz
Joined: 2008-12-16,
User offline. Last seen 29 weeks 3 days ago.
Re: Cyclic reference?
David,

Given Eric's trick, you can achieve essentially the same effect with abstract types instead of parameterized types.

  trait AboutMe {
    type T >: this.type with AboutMe
  }
 
  class Test extends AboutMe {
    type T = Test
  }

  object Test extends AboutMe {
    type T = this.type
  }

--j

On Wed, Feb 11, 2009 at 12:55 PM, David Pollak <feeder [dot] of [dot] the [dot] bears [at] gmail [dot] com> wrote:
Howdy,
If I've got a trait that takes its implementor as a parameter:
trait AboutMe[A <: AboutMe[A]] {
  self: A =>
}

I can create a class that extends the trait:
class Test extends AboutMe[Test] // works

But I can't seem to create an object that extends the trait without going through the intermediate step of creating a class and making the object an instance of the class.
object T2 extends AboutMe[T2] // fails
object T2 extends AboutMe[T2.type] // fails

Any advice would be appreciated.
Thanks,
David
--
Lift, the simply functional web framework http://liftweb.net
Beginning Scala http://www.apress.com/book/view/1430219890
Follow me: http://twitter.com/dpp
Git some: http://github.com/dpp

David Pollak
Joined: 2008-12-16,
User offline. Last seen 42 years 45 weeks ago.
Re: Cyclic reference?
Jorge and Eric,
Thanks for the trick, but I need the type to be a type parameter in order to make sure that the types of other traits have the same type:
trait Table[MyType <: Table[MyType]] {   def find(qp: QueryParam[MyType])...}
trait QueryParam[T <: Table[T]]...

Thanks,
David

On Fri, Feb 13, 2009 at 2:10 AM, Jorge Ortiz <jorge [dot] ortiz [at] gmail [dot] com> wrote:
David,

Given Eric's trick, you can achieve essentially the same effect with abstract types instead of parameterized types.

  trait AboutMe {
    type T >: this.type with AboutMe
  }
 
  class Test extends AboutMe {
    type T = Test
  }

  object Test extends AboutMe {
    type T = this.type
  }

--j

On Wed, Feb 11, 2009 at 12:55 PM, David Pollak <feeder [dot] of [dot] the [dot] bears [at] gmail [dot] com> wrote:
Howdy,
If I've got a trait that takes its implementor as a parameter:
trait AboutMe[A <: AboutMe[A]] {
  self: A =>
}

I can create a class that extends the trait:
class Test extends AboutMe[Test] // works

But I can't seem to create an object that extends the trait without going through the intermediate step of creating a class and making the object an instance of the class.
object T2 extends AboutMe[T2] // fails
object T2 extends AboutMe[T2.type] // fails

Any advice would be appreciated.
Thanks,
David
--
Lift, the simply functional web framework http://liftweb.net
Beginning Scala http://www.apress.com/book/view/1430219890
Follow me: http://twitter.com/dpp
Git some: http://github.com/dpp




--
Lift, the simply functional web framework http://liftweb.net
Beginning Scala http://www.apress.com/book/view/1430219890
Follow me: http://twitter.com/dpp
Git some: http://github.com/dpp
Jorge Ortiz
Joined: 2008-12-16,
User offline. Last seen 29 weeks 3 days ago.
Re: Cyclic reference?
  trait Table {
    type MyType >: this.type
    trait QueryParam
   
    def find(qp: QueryParam)
  }

?

On Thu, Feb 12, 2009 at 5:38 PM, Jorge Ortiz <jorge [dot] ortiz [at] gmail [dot] com> wrote:
This bit of code led me to discover several... unfortunate... aspects of the type system.

1)

Class types can be used as parameters to types the class extends, but singleton types can't be used as parameters to types the singleton extends.

trait Param[T]
class Test1 extends Param[Test1]    // works
object Test2 extends Param[Test2.type]    // fails

2)

Parametrized types can be used as self types, but abstract types can't.

trait Self1[T] { self: T => }    // works
trait Self2 { self:T => type T }    // fails

3)

Parametrized types can have cyclic references, but abstract types can't.

trait Param[T]
trait Abs { type T }
trait Cyclic1[A <: Param[A]]    // works
trait Cyclic2[A <: Abs { type T = A }]    // fails
trait Cyclic3 { type A <: Abs { type T = A } }    // fails
trait Cyclic4 { type A <: Param[A] }   // works



Are these as intended or can I file tickets on them?

--j

On Wed, Feb 11, 2009 at 12:55 PM, David Pollak <feeder [dot] of [dot] the [dot] bears [at] gmail [dot] com> wrote:
Howdy,
If I've got a trait that takes its implementor as a parameter:
trait AboutMe[A <: AboutMe[A]] {
  self: A =>
}

I can create a class that extends the trait:
class Test extends AboutMe[Test] // works

But I can't seem to create an object that extends the trait without going through the intermediate step of creating a class and making the object an instance of the class.
object T2 extends AboutMe[T2] // fails
object T2 extends AboutMe[T2.type] // fails

Any advice would be appreciated.
Thanks,
David
--
Lift, the simply functional web framework http://liftweb.net
Beginning Scala http://www.apress.com/book/view/1430219890
Follow me: http://twitter.com/dpp
Git some: http://github.com/dpp


David Pollak
Joined: 2008-12-16,
User offline. Last seen 42 years 45 weeks ago.
Re: Cyclic reference?


On Fri, Feb 13, 2009 at 9:33 AM, Jorge Ortiz <jorge [dot] ortiz [at] gmail [dot] com> wrote:
  trait Table {
    type MyType >: this.type
    trait QueryParam
   
    def find(qp: QueryParam)
  }

?

Then you have to do wacky things to add QueryParams that are not defined in the Table trait itself.  Plus, you have to import the concrete object into your scope or you'll be writing MyTable.OrderBy(...) all the time.
The overall cost of creating the class and then an object from the class seems to me to be the least worst of the alternative. 


On Thu, Feb 12, 2009 at 5:38 PM, Jorge Ortiz <jorge [dot] ortiz [at] gmail [dot] com> wrote:
This bit of code led me to discover several... unfortunate... aspects of the type system.

1)

Class types can be used as parameters to types the class extends, but singleton types can't be used as parameters to types the singleton extends.

trait Param[T]
class Test1 extends Param[Test1]    // works
object Test2 extends Param[Test2.type]    // fails

2)

Parametrized types can be used as self types, but abstract types can't.

trait Self1[T] { self: T => }    // works
trait Self2 { self:T => type T }    // fails

3)

Parametrized types can have cyclic references, but abstract types can't.

trait Param[T]
trait Abs { type T }
trait Cyclic1[A <: Param[A]]    // works
trait Cyclic2[A <: Abs { type T = A }]    // fails
trait Cyclic3 { type A <: Abs { type T = A } }    // fails
trait Cyclic4 { type A <: Param[A] }   // works



Are these as intended or can I file tickets on them?

--j

On Wed, Feb 11, 2009 at 12:55 PM, David Pollak <feeder [dot] of [dot] the [dot] bears [at] gmail [dot] com> wrote:
Howdy,
If I've got a trait that takes its implementor as a parameter:
trait AboutMe[A <: AboutMe[A]] {
  self: A =>
}

I can create a class that extends the trait:
class Test extends AboutMe[Test] // works

But I can't seem to create an object that extends the trait without going through the intermediate step of creating a class and making the object an instance of the class.
object T2 extends AboutMe[T2] // fails
object T2 extends AboutMe[T2.type] // fails

Any advice would be appreciated.
Thanks,
David
--
Lift, the simply functional web framework http://liftweb.net
Beginning Scala http://www.apress.com/book/view/1430219890
Follow me: http://twitter.com/dpp
Git some: http://github.com/dpp





--
Lift, the simply functional web framework http://liftweb.net
Beginning Scala http://www.apress.com/book/view/1430219890
Follow me: http://twitter.com/dpp
Git some: http://github.com/dpp
odersky
Joined: 2008-07-29,
User offline. Last seen 45 weeks 6 days ago.
Re: Cyclic reference?

On Fri, Feb 13, 2009 at 2:38 AM, Jorge Ortiz wrote:
> This bit of code led me to discover several... unfortunate... aspects of the
> type system.
>
> 1)
>
> Class types can be used as parameters to types the class extends, but
> singleton types can't be used as parameters to types the singleton extends.
>
> trait Param[T]
> class Test1 extends Param[Test1] // works
> object Test2 extends Param[Test2.type] // fails
>
That's how the type system is supposed to work, unfortunately.

Essentially: you have the following dependencies:

- Before a value is known, its type must be elaborated.
- Before a type is computed, its parents must be elaborated.

There's an exception for classes, where a class is counted as elaborated
even before its parents are elaborated. But that's a local exception.
Essentially, to compute the type of a class,
elaborate its type parameters, mark the class as elaborated, then
elaborate its parents. This rule does not extend to values different
from the class.

Now, we could enlarge the exception, at a price of complexity. But I
think what you had in mind was something else anyway: You wanted to
close the recursion with the unnamed class that underlies the object.
Since that class does not have a name, you picked the singleton type
of the object instead. We are currently thinking of making the name of
the class that implements an object available, probably as `object
Foo'. So then you could write:

object Test2 extends Param[object Test2]

The advantage of this scheme is that it would also give us the
possibility of inheriting singleton classes, and this would be useful
for virtual objects (where an inner object gets refined in a
subclass).

> Parametrized types can be used as self types, but abstract types can't.
>
> trait Self1[T] { self: T => } // works
> trait Self2 { self:T => type T } // fails
>
That's again as it's supposed to be. There's a dependency that members
of a class are elaborated only after the
enclosing class is elaborated, and the self type belongs to the class.
(You might ask why all these picky rules? in short: to prevent the
compiler from going into infinite recursions when it encounters some
non-sensical programs).

> Parametrized types can have cyclic references, but abstract types can't.
>
> trait Param[T]
> trait Abs { type T }
> trait Cyclic1[A <: Param[A]] // works
> trait Cyclic2[A <: Abs { type T = A }] // fails
> trait Cyclic3 { type A <: Abs { type T = A } } // fails
> trait Cyclic4 { type A <: Param[A] } // works
>
This one's a bug, I think. I just checked in a version into trunk
which should fix it.

Cheers

- Martin

David Pollak
Joined: 2008-12-16,
User offline. Last seen 42 years 45 weeks ago.
Re: Cyclic reference?


On Sun, Feb 15, 2009 at 8:54 AM, martin odersky <martin [dot] odersky [at] epfl [dot] ch> wrote:
On Fri, Feb 13, 2009 at 2:38 AM, Jorge Ortiz <jorge [dot] ortiz [at] gmail [dot] com> wrote:
> This bit of code led me to discover several... unfortunate... aspects of the
> type system.
>
> 1)
>
> Class types can be used as parameters to types the class extends, but
> singleton types can't be used as parameters to types the singleton extends.
>
> trait Param[T]
> class Test1 extends Param[Test1]    // works
> object Test2 extends Param[Test2.type]    // fails
>
That's how the type system is supposed to work, unfortunately.

Essentially: you have the following dependencies:

 - Before a value is known, its type must be elaborated.
 - Before a type is computed, its parents must be elaborated.

There's an exception for classes, where a class is counted as elaborated
even before its parents are elaborated. But that's a local exception.
Essentially, to compute the type of a class,
elaborate its type parameters, mark the class as elaborated, then
elaborate its parents. This rule does not extend to values different
from the class.

Now, we could enlarge the exception, at a price of complexity. But I
think what you had in mind was something else anyway: You wanted to
close the recursion with the unnamed class that underlies the object.
Since that class does not have a name, you picked the singleton type
of the object instead. We are currently thinking of making the name of
the class that implements an object available, probably as `object
Foo'. So then you could write:

object Test2 extends Param[object Test2]

This would be great! 

The advantage of this scheme is that it would also give us the
possibility of inheriting singleton classes, and this would be useful
for virtual objects (where an inner object gets refined in a
subclass).

That would be very, very, very nice. 

> Parametrized types can be used as self types, but abstract types can't.
>
> trait Self1[T] { self: T => }    // works
> trait Self2 { self:T => type T }    // fails
>
That's again as it's supposed to be. There's a dependency that members
of a class are elaborated only after the
enclosing class is elaborated, and the self type belongs to the class.
(You might ask why all these picky rules? in short: to prevent the
compiler from going into infinite recursions when it encounters some
non-sensical programs).

> Parametrized types can have cyclic references, but abstract types can't.
>
> trait Param[T]
> trait Abs { type T }
> trait Cyclic1[A <: Param[A]]    // works
> trait Cyclic2[A <: Abs { type T = A }]    // fails
> trait Cyclic3 { type A <: Abs { type T = A } }    // fails
> trait Cyclic4 { type A <: Param[A] }   // works
>
This one's a bug, I think. I just checked in a version into trunk
which should fix it.

On a related note, is there a way to have a wildcard for:
trait Creature[A <: Creature[A]]
I tried Creature[_], but that failed.
I tried Creature[(T forSome {type T <: Creature[T]})], but that failed.
Thanks,
David 


Cheers

 - Martin



--
Lift, the simply functional web framework http://liftweb.net
Beginning Scala http://www.apress.com/book/view/1430219890
Follow me: http://twitter.com/dpp
Git some: http://github.com/dpp
milessabin
Joined: 2008-08-11,
User offline. Last seen 33 weeks 3 days ago.
Re: Cyclic reference?

On Mon, Feb 16, 2009 at 3:10 AM, David Pollak
wrote:
> On a related note, is there a way to have a wildcard for:
> trait Creature[A <: Creature[A]]
> I tried Creature[_], but that failed.
> I tried Creature[(T forSome {type T <: Creature[T]})], but that failed.

Try,

Creature[T] forSome { type T <: Creature[T] }

Cheers,

Miles

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