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

Design question regarding parameterized types and type constraints

20 replies
normen.mueller
Joined: 2008-10-31,
User offline. Last seen 3 years 8 weeks ago.

He,

I want to set up a trait with a contravariant type parameter whereas the parameterized type has to have a specific function, like:

trait System[-T <: {def name: String}] {
...
}

So far so good. But now, I want to instantiate ``System'' with, for example, ``scala.xml.Node'', like:

val s = new System[scala.xml.Node] {
...
}

``scala.xml.Node'', however, does not have the function ``name''.

So can anyone help me out to get the design right?

Cheers,
--
Normen Müller

dcsobral
Joined: 2009-04-23,
User offline. Last seen 38 weeks 5 days ago.
Re: Design question regarding parameterized types and type con
Being contra-variant, >: would be a more meaningful bound, but I don't think <: and >: make any sense for structural types.

On Wed, Jan 13, 2010 at 5:32 PM, Normen Müller <normen.mueller@googlemail.com> wrote:
He,

I want to set up a trait with a contravariant type parameter whereas the parameterized type has to have a specific function, like:

trait System[-T <: {def name: String}] {
 ...
}

So far so good.  But now, I want to instantiate ``System'' with, for example, ``scala.xml.Node'', like:

val s = new System[scala.xml.Node] {
 ...
}

``scala.xml.Node'', however, does not have the function ``name''.

So can anyone help me out to get the design right?

Cheers,
--
Normen Müller




--
Daniel C. Sobral

I travel to the future all the time.
dcsobral
Joined: 2009-04-23,
User offline. Last seen 38 weeks 5 days ago.
Re: Design question regarding parameterized types and type con
Err, I'm sorry, mistyped. I meant to say co-variant and contra-variant don't make any sense for structural types. But, who knows? I might be wrong. :-)

On Wed, Jan 13, 2010 at 5:47 PM, Daniel Sobral <dcsobral@gmail.com> wrote:
Being contra-variant, >: would be a more meaningful bound, but I don't think <: and >: make any sense for structural types.

On Wed, Jan 13, 2010 at 5:32 PM, Normen Müller <normen.mueller@googlemail.com> wrote:
He,

I want to set up a trait with a contravariant type parameter whereas the parameterized type has to have a specific function, like:

trait System[-T <: {def name: String}] {
 ...
}

So far so good.  But now, I want to instantiate ``System'' with, for example, ``scala.xml.Node'', like:

val s = new System[scala.xml.Node] {
 ...
}

``scala.xml.Node'', however, does not have the function ``name''.

So can anyone help me out to get the design right?

Cheers,
--
Normen Müller




--
Daniel C. Sobral

I travel to the future all the time.



--
Daniel C. Sobral

I travel to the future all the time.
Stefan Langer
Joined: 2009-10-23,
User offline. Last seen 42 years 45 weeks ago.
Re: Design question regarding parameterized types and type con
Try doing a view bound and then provide a implicit conversion fro xml.Node to a type that contains name.

Regards
Stefan

2010/1/13 Normen Müller <normen.mueller@googlemail.com>
He,

I want to set up a trait with a contravariant type parameter whereas the parameterized type has to have a specific function, like:

trait System[-T <: {def name: String}] {
 ...
}

So far so good.  But now, I want to instantiate ``System'' with, for example, ``scala.xml.Node'', like:

val s = new System[scala.xml.Node] {
 ...
}

``scala.xml.Node'', however, does not have the function ``name''.

So can anyone help me out to get the design right?

Cheers,
--
Normen Müller


normen.mueller
Joined: 2008-10-31,
User offline. Last seen 3 years 8 weeks ago.
Re: Design question regarding parameterized types and type cons

He Daniel,

On Jan 13, 2010, at 8:47 PM, Daniel Sobral wrote:
> Err, I'm sorry, mistyped. I meant to say co-variant and contra-variant don't make any sense for structural types. But, who knows? I might be wrong. :-)

What do you mean by ``structural types''? And why does variance annotation (at least for you) doesn't make sense here?

Sorry, but I am still in the process of learning more about type theory. And I am not quite sure if I understood ``structural types'' correctly. Can you please explain a bit more in detail?

> On Wed, Jan 13, 2010 at 5:47 PM, Daniel Sobral wrote:
> Being contra-variant, >: would be a more meaningful bound, but I don't think <: and >: make any sense for structural types.
>
> On Wed, Jan 13, 2010 at 5:32 PM, Normen Müller wrote:
> He,
>
> I want to set up a trait with a contravariant type parameter whereas the parameterized type has to have a specific function, like:
>
> trait System[-T <: {def name: String}] {
> ...
> }
>
> So far so good. But now, I want to instantiate ``System'' with, for example, ``scala.xml.Node'', like:
>
> val s = new System[scala.xml.Node] {
> ...
> }
>
> ``scala.xml.Node'', however, does not have the function ``name''.
>
> So can anyone help me out to get the design right?

Cheers,
--
Normen Müller

dcsobral
Joined: 2009-04-23,
User offline. Last seen 38 weeks 5 days ago.
Re: Design question regarding parameterized types and type con
Structural type:
    T <: {def name: String}
T does not denote a class. T stands for all objects whose structure include a method called "name" taking no parameters and returning String.
So, what does it mean for T to be contra-variant (-T)? Co-variance and contra-variance indicates how subtyping relates to subclassing, but there is no class here.

On Thu, Jan 14, 2010 at 9:12 AM, Normen Müller <normen.mueller@googlemail.com> wrote:
He Daniel,

On Jan 13, 2010, at 8:47 PM, Daniel Sobral wrote:
> Err, I'm sorry, mistyped. I meant to say co-variant and contra-variant don't make any sense for structural types. But, who knows? I might be wrong. :-)

What do you mean by ``structural types''?  And why does variance annotation (at least for you) doesn't make sense here?

Sorry, but I am still in the process of learning more about type theory.  And I am not quite sure if I understood ``structural types'' correctly.   Can you please explain a bit more in detail?

> On Wed, Jan 13, 2010 at 5:47 PM, Daniel Sobral <dcsobral@gmail.com> wrote:
> Being contra-variant, >: would be a more meaningful bound, but I don't think <: and >: make any sense for structural types.
>
> On Wed, Jan 13, 2010 at 5:32 PM, Normen Müller <normen.mueller@googlemail.com> wrote:
> He,
>
> I want to set up a trait with a contravariant type parameter whereas the parameterized type has to have a specific function, like:
>
> trait System[-T <: {def name: String}] {
>  ...
> }
>
> So far so good.  But now, I want to instantiate ``System'' with, for example, ``scala.xml.Node'', like:
>
> val s = new System[scala.xml.Node] {
>  ...
> }
>
> ``scala.xml.Node'', however, does not have the function ``name''.
>
> So can anyone help me out to get the design right?

Cheers,
--
Normen Müller




--
Daniel C. Sobral

I travel to the future all the time.
normen.mueller
Joined: 2008-10-31,
User offline. Last seen 3 years 8 weeks ago.
Re: Design question regarding parameterized types and type cons

On Jan 14, 2010, at 12:24 PM, Daniel Sobral wrote:

> Structural type:
>
> T <: {def name: String}
>
> T does not denote a class. T stands for all objects whose structure include a method called "name" taking no parameters and returning String.

Aha, I got that! Thanks!!

> So, what does it mean for T to be contra-variant (-T)? Co-variance and contra-variance indicates how subtyping relates to subclassing, but there is no class here.

Isn't it ``System is contra-variant in its type parameter T''?

Anyways, I am trying to use Stefan's suggestion, but don't know how to do it exactly :(
Can you help?

Stefan said: ``Try doing a view bound and then provide a implicit conversion fro xml.Node to a type that contains name.''

>
> On Thu, Jan 14, 2010 at 9:12 AM, Normen Müller wrote:
> He Daniel,
>
> On Jan 13, 2010, at 8:47 PM, Daniel Sobral wrote:
> > Err, I'm sorry, mistyped. I meant to say co-variant and contra-variant don't make any sense for structural types. But, who knows? I might be wrong. :-)
>
> What do you mean by ``structural types''? And why does variance annotation (at least for you) doesn't make sense here?
>
> Sorry, but I am still in the process of learning more about type theory. And I am not quite sure if I understood ``structural types'' correctly. Can you please explain a bit more in detail?
>
> > On Wed, Jan 13, 2010 at 5:47 PM, Daniel Sobral wrote:
> > Being contra-variant, >: would be a more meaningful bound, but I don't think <: and >: make any sense for structural types.
> >
> > On Wed, Jan 13, 2010 at 5:32 PM, Normen Müller wrote:
> > He,
> >
> > I want to set up a trait with a contravariant type parameter whereas the parameterized type has to have a specific function, like:
> >
> > trait System[-T <: {def name: String}] {
> > ...
> > }
> >
> > So far so good. But now, I want to instantiate ``System'' with, for example, ``scala.xml.Node'', like:
> >
> > val s = new System[scala.xml.Node] {
> > ...
> > }
> >
> > ``scala.xml.Node'', however, does not have the function ``name''.
> >
> > So can anyone help me out to get the design right?
>
> Cheers,
> --
> Normen Müller
>
>
>
>

normen.mueller
Joined: 2008-10-31,
User offline. Last seen 3 years 8 weeks ago.
Re: Design question regarding parameterized types and type cons

On Jan 14, 2010, at 9:23 AM, Stefan Langer wrote:

> Try doing a view bound and then provide a implicit conversion fro xml.Node to a type that contains name.

Do you mean sth. like that:

trait Identifiable[T] { val id: T }
trait System[-T <% Identifiable[String]]

I guess not, cause this doesn't compile. Can you please explain how exactly declare your suggested view bound?

> 2010/1/13 Normen Müller
> He,
>
> I want to set up a trait with a contravariant type parameter whereas the parameterized type has to have a specific function, like:
>
> trait System[-T <: {def name: String}] {
> ...
> }
>
> So far so good. But now, I want to instantiate ``System'' with, for example, ``scala.xml.Node'', like:
>
> val s = new System[scala.xml.Node] {
> ...
> }
>
> ``scala.xml.Node'', however, does not have the function ``name''.
>
> So can anyone help me out to get the design right?

Cheers,
--
Normen Müller

Michal Politowski 2
Joined: 2009-09-15,
User offline. Last seen 42 years 45 weeks ago.
Re: Design question regarding parameterized types and type cons

On Thu, 14 Jan 2010 09:24:52 -0200, Daniel Sobral wrote:
> Structural type:
>
> T <: {def name: String}
>
> T does not denote a class. T stands for all objects whose structure include
> a method called "name" taking no parameters and returning String.
>
> So, what does it mean for T to be contra-variant (-T)? Co-variance and
> contra-variance indicates how subtyping relates to subclassing, but there is
> no class here.

I think there is some confusion here. There is in my mind no connection
between the type bound, whether structural or nominal, which places
restrictions on values of the type parameter, and the variance annotation
specifying subtyping relations between oncrete instantiations of
a parameterized type.

Concrete example:
$ scala
Welcome to Scala version 2.7.7final (Java HotSpot(TM) Server VM, Java 1.6.0_17).
Type in expressions to have them evaluated.
Type :help for more information.

scala> class Foo[T <: { def bar: Unit }]
defined class Foo

scala> class Bar { def bar {} }
defined class Bar

scala> class Baz extends Bar
defined class Baz

scala> val foo: Foo[Bar] = new Foo[Baz]
:7: error: type mismatch;
found : Foo[Baz]
required: Foo[Bar]
val foo: Foo[Bar] = new Foo[Baz]
^

scala> class Foo[+T <: { def bar: Unit }]
defined class Foo

scala> val foo: Foo[Bar] = new Foo[Baz]
foo: Foo[Bar] = Foo@645fd

scala> class Foo[-T <: { def bar: Unit }]
defined class Foo

scala> val foo: Foo[Bar] = new Foo[Baz]
:7: error: type mismatch;
found : Foo[Baz]
required: Foo[Bar]
val foo: Foo[Bar] = new Foo[Baz]
^

scala> val foo: Foo[Baz] = new Foo[Bar]
foo: Foo[Baz] = Foo@61a414

normen.mueller
Joined: 2008-10-31,
User offline. Last seen 3 years 8 weeks ago.
Re: Design question regarding parameterized types and type cons

He Michal,

On Jan 14, 2010, at 12:56 PM, Michal Politowski wrote:

> On Thu, 14 Jan 2010 09:24:52 -0200, Daniel Sobral wrote:
>> Structural type:
>>
>> T <: {def name: String}
>>
>> T does not denote a class. T stands for all objects whose structure include
>> a method called "name" taking no parameters and returning String.
>>
>> So, what does it mean for T to be contra-variant (-T)? Co-variance and
>> contra-variance indicates how subtyping relates to subclassing, but there is
>> no class here.
>
> I think there is some confusion here. There is in my mind no connection
> between the type bound, whether structural or nominal, which places
> restrictions on values of the type parameter, and the variance annotation
> specifying subtyping relations between oncrete instantiations of
> a parameterized type.
>
> Concrete example:
> $ scala
> Welcome to Scala version 2.7.7final (Java HotSpot(TM) Server VM, Java 1.6.0_17).
> Type in expressions to have them evaluated.
> Type :help for more information.
>
> scala> class Foo[T <: { def bar: Unit }]
> defined class Foo
>
> scala> class Bar { def bar {} }
> defined class Bar
>
> scala> class Baz extends Bar
> defined class Baz
>
> scala> val foo: Foo[Bar] = new Foo[Baz]
> :7: error: type mismatch;
> found : Foo[Baz]
> required: Foo[Bar]
> val foo: Foo[Bar] = new Foo[Baz]
> ^
>
> scala> class Foo[+T <: { def bar: Unit }]
> defined class Foo
>
> scala> val foo: Foo[Bar] = new Foo[Baz]
> foo: Foo[Bar] = Foo@645fd
>
> scala> class Foo[-T <: { def bar: Unit }]
> defined class Foo
>
> scala> val foo: Foo[Bar] = new Foo[Baz]
> :7: error: type mismatch;
> found : Foo[Baz]
> required: Foo[Bar]
> val foo: Foo[Bar] = new Foo[Baz]
> ^
>
> scala> val foo: Foo[Baz] = new Foo[Bar]
> foo: Foo[Baz] = Foo@61a414

Sorry, I don't exactly get your point :(

Do your concrete examples point out, that what I want to design is not possible?

I still believe that there must be a way to express sth. like:

trait Identifiable[T] { val id: T }
trait System[-T <% Identifiable[String]] {
// here I have to access ``id''
def ordered[S <: T](l: S): Boolean = error("not yet implemented")
}
val s = new System[scala.xml.Node] {
...
}

Cheers,
--
Normen Müller

normen.mueller
Joined: 2008-10-31,
User offline. Last seen 3 years 8 weeks ago.
Re: Design question regarding parameterized types and type cons

So far I have now the following (which compiles but isn't testes during runtime yet):

object INode {
implicit def toIdentifiable(n: scala.xml.Node) =
new Identifiable[String] { val id: String = n.label }
}

trait System[-T] {
def ordered[S <: T <% Identifiable[String]](l: S): Boolean = {
l.id // now I can access ``id''
true
}
}

val s = new System[scala.xml.Node] {
// this line, though, is not needed for successful compilation
// that's way I am not sure if this design is correct :-\
import IdentifiableNode._
}

On Jan 14, 2010, at 1:07 PM, Normen Müller wrote:

> He Michal,
>
> On Jan 14, 2010, at 12:56 PM, Michal Politowski wrote:
>
>> On Thu, 14 Jan 2010 09:24:52 -0200, Daniel Sobral wrote:
>>> Structural type:
>>>
>>> T <: {def name: String}
>>>
>>> T does not denote a class. T stands for all objects whose structure include
>>> a method called "name" taking no parameters and returning String.
>>>
>>> So, what does it mean for T to be contra-variant (-T)? Co-variance and
>>> contra-variance indicates how subtyping relates to subclassing, but there is
>>> no class here.
>>
>> I think there is some confusion here. There is in my mind no connection
>> between the type bound, whether structural or nominal, which places
>> restrictions on values of the type parameter, and the variance annotation
>> specifying subtyping relations between oncrete instantiations of
>> a parameterized type.
>>
>> Concrete example:
>> $ scala
>> Welcome to Scala version 2.7.7final (Java HotSpot(TM) Server VM, Java 1.6.0_17).
>> Type in expressions to have them evaluated.
>> Type :help for more information.
>>
>> scala> class Foo[T <: { def bar: Unit }]
>> defined class Foo
>>
>> scala> class Bar { def bar {} }
>> defined class Bar
>>
>> scala> class Baz extends Bar
>> defined class Baz
>>
>> scala> val foo: Foo[Bar] = new Foo[Baz]
>> :7: error: type mismatch;
>> found : Foo[Baz]
>> required: Foo[Bar]
>> val foo: Foo[Bar] = new Foo[Baz]
>> ^
>>
>> scala> class Foo[+T <: { def bar: Unit }]
>> defined class Foo
>>
>> scala> val foo: Foo[Bar] = new Foo[Baz]
>> foo: Foo[Bar] = Foo@645fd
>>
>> scala> class Foo[-T <: { def bar: Unit }]
>> defined class Foo
>>
>> scala> val foo: Foo[Bar] = new Foo[Baz]
>> :7: error: type mismatch;
>> found : Foo[Baz]
>> required: Foo[Bar]
>> val foo: Foo[Bar] = new Foo[Baz]
>> ^
>>
>> scala> val foo: Foo[Baz] = new Foo[Bar]
>> foo: Foo[Baz] = Foo@61a414
>
> Sorry, I don't exactly get your point :(
>
> Do your concrete examples point out, that what I want to design is not possible?
>
> I still believe that there must be a way to express sth. like:
>
> trait Identifiable[T] { val id: T }
> trait System[-T <% Identifiable[String]] {
> // here I have to access ``id''
> def ordered[S <: T](l: S): Boolean = error("not yet implemented")
> }
> val s = new System[scala.xml.Node] {
> ...
> }
>
> Cheers,
> --
> Normen Müller
>

Cheers,
--
Normen Müller

Michal Politowski 2
Joined: 2009-09-15,
User offline. Last seen 42 years 45 weeks ago.
Re: Design question regarding parameterized types and type cons

On Thu, 14 Jan 2010 13:07:01 +0100, Normen Müller wrote:
> He Michal,
>
> On Jan 14, 2010, at 12:56 PM, Michal Politowski wrote:
>
> > On Thu, 14 Jan 2010 09:24:52 -0200, Daniel Sobral wrote:
[...]
> Sorry, I don't exactly get your point :(
>
> Do your concrete examples point out, that what I want to design is not possible?

Sorry for any confusion. I wasn't actually referring to your design at all,
only to Daniel's post about nominal types and variance.

> I still believe that there must be a way to express sth. like:
>
> trait Identifiable[T] { val id: T }
> trait System[-T <% Identifiable[String]] {
> // here I have to access ``id''
> def ordered[S <: T](l: S): Boolean = error("not yet implemented")
> }
> val s = new System[scala.xml.Node] {
> ...
> }

As for this, I'm not sure I undestand your design, so one question first.
You want to access the `id` property of what object?
In the above, apart from the fact that traits cannot have parameters
with type bounds, so System would have to be a class,
you can certainly use eg. l.id in the `ordered` method, eg.:
def ordered[S <: T](l: S): Boolean = if (l.id.equalsIgnoreCase("foo")) true else false

Michal Politowski 2
Joined: 2009-09-15,
User offline. Last seen 42 years 45 weeks ago.
Re: Design question regarding parameterized types and type cons

On Thu, 14 Jan 2010 13:24:56 +0100, Normen Müller wrote:
> So far I have now the following (which compiles but isn't testes during runtime yet):
>
> object INode {
> implicit def toIdentifiable(n: scala.xml.Node) =
> new Identifiable[String] { val id: String = n.label }
> }
>
> trait System[-T] {
> def ordered[S <: T <% Identifiable[String]](l: S): Boolean = {
> l.id // now I can access ``id''
> true
> }
> }
>
> val s = new System[scala.xml.Node] {
> // this line, though, is not needed for successful compilation
> // that's way I am not sure if this design is correct :-\
> import IdentifiableNode._
> }

Well, in this example only the ordered method needs the implicit conversion,
so you need the import as soon as you actually call it.

val s = new System[scala.xml.Node] {
import INode._
val foo = ordered()
}

normen.mueller
Joined: 2008-10-31,
User offline. Last seen 3 years 8 weeks ago.
Re: Design question regarding parameterized types and type cons

On Jan 14, 2010, at 1:44 PM, Michal Politowski wrote:

> On Thu, 14 Jan 2010 13:24:56 +0100, Normen Müller wrote:
>> So far I have now the following (which compiles but isn't testes during runtime yet):
>>
>> object INode {
>> implicit def toIdentifiable(n: scala.xml.Node) =
>> new Identifiable[String] { val id: String = n.label }
>> }
>>
>> trait System[-T] {
>> def ordered[S <: T <% Identifiable[String]](l: S): Boolean = {
>> l.id // now I can access ``id''
>> true
>> }
>> }
>>
>> val s = new System[scala.xml.Node] {
>> // this line, though, is not needed for successful compilation
>> // that's way I am not sure if this design is correct :-\
>> import IdentifiableNode._
>> }
>
> Well, in this example only the ordered method needs the implicit conversion,
> so you need the import as soon as you actually call it.
>
> val s = new System[scala.xml.Node] {
> import INode._
> val foo = ordered()
> }

Understand. Thanks! I currently working on it and let you know how it works.

Cheers,
--
Normen Müller

normen.mueller
Joined: 2008-10-31,
User offline. Last seen 3 years 8 weeks ago.
Re: Design question regarding parameterized types and type cons

He,

I still struggling with my design :(

I guess I could bypass the view bound issue, but why doesn't the following compile:
(Sorry for posting to the same thread, but I don't exactly know how to name the new one regarding the compiler error)

import scala.xml.{Node, MetaData}

//not sure if covariance is needed here
case class Spec[+T](val cs: Seq[T])

trait System[-T] {
def spec[S <: T](l: T): Spec[S]
}

object Test {
val s = new System[Node] {
def spec[S <: Node](n: Node) = {
n match {
case Node(l, as, cs@_*) => Spec(cs) // doesn't compile!?
}
}
}
}

Why is Seq[S] not a subtype of Seq[Node]? Or, what am I missing here???

Cheers,
--
Normen Müller

Stefan Langer
Joined: 2009-10-23,
User offline. Last seen 42 years 45 weeks ago.
Re: Design question regarding parameterized types and type con
Because Seq[S] is not covariant and there for Seq[Node] is not a subtype of Seq[S]

Seq[+S] should work.



2010/1/14 Normen Müller <normen.mueller@googlemail.com>
He,

I still struggling with my design :(

I guess I could bypass the view bound issue, but why doesn't the following compile:
(Sorry for posting to the same thread, but I don't exactly know how to name the new one regarding the compiler error)

import scala.xml.{Node, MetaData}

//not sure if covariance is needed here
case class Spec[+T](val cs: Seq[T])

trait System[-T] {
 def spec[S <: T](l: T): Spec[S]
}

object Test {
 val s = new System[Node] {
   def spec[S <: Node](n: Node) = {
     n match {
       case Node(l, as, cs@_*) => Spec(cs) // doesn't compile!?
     }
   }
 }
}

Why is Seq[S] not a subtype of Seq[Node]?  Or, what am I missing here???

Cheers,
--
Normen Müller


normen.mueller
Joined: 2008-10-31,
User offline. Last seen 3 years 8 weeks ago.
Re: Design question regarding parameterized types and type cons

On Jan 15, 2010, at 9:52 AM, Stefan Langer wrote:

> Because Seq[S] is not covariant and there for Seq[Node] is not a
> subtype of Seq[S]
>
> Seq[+S] should work.

But as I can't change the Scala Lib, I guess I should use List[+T]
instead. Thanks for your explanation!

> 2010/1/14 Normen Müller
> He,
>
> I still struggling with my design :(
>
> I guess I could bypass the view bound issue, but why doesn't the
> following compile:
> (Sorry for posting to the same thread, but I don't exactly know how
> to name the new one regarding the compiler error)
>
> import scala.xml.{Node, MetaData}
>
> //not sure if covariance is needed here
> case class Spec[+T](val cs: Seq[T])
>
> trait System[-T] {
> def spec[S <: T](l: T): Spec[S]
> }
>
> object Test {
> val s = new System[Node] {
> def spec[S <: Node](n: Node) = {
> n match {
> case Node(l, as, cs@_*) => Spec(cs) // doesn't compile!?
> }
> }
> }
> }
>
> Why is Seq[S] not a subtype of Seq[Node]? Or, what am I missing
> here???
>
> Cheers,
> --
> Normen Müller
>
>

Cheers,
--
Normen Müller

Stefan Langer
Joined: 2009-10-23,
User offline. Last seen 42 years 45 weeks ago.
Re: Design question regarding parameterized types and type con
Just rechecked and Seq is covariant at least in 2.7.7

2010/1/15 Normen Müller <normen.mueller@googlemail.com>
On Jan 15, 2010, at 9:52 AM, Stefan Langer wrote:

Because Seq[S] is not covariant and there for Seq[Node] is not a subtype of Seq[S]

Seq[+S] should work.

But as I can't change the Scala Lib, I guess I should use List[+T] instead.  Thanks for your explanation!

2010/1/14 Normen Müller <normen.mueller@googlemail.com>
He,

I still struggling with my design :(

I guess I could bypass the view bound issue, but why doesn't the following compile:
(Sorry for posting to the same thread, but I don't exactly know how to name the new one regarding the compiler error)

import scala.xml.{Node, MetaData}

//not sure if covariance is needed here
case class Spec[+T](val cs: Seq[T])

trait System[-T] {
 def spec[S <: T](l: T): Spec[S]
}

object Test {
 val s = new System[Node] {
  def spec[S <: Node](n: Node) = {
    n match {
      case Node(l, as, cs@_*) => Spec(cs) // doesn't compile!?
    }
  }
 }
}

Why is Seq[S] not a subtype of Seq[Node]?  Or, what am I missing here???

Cheers,
--
Normen Müller




Cheers,
--
Normen Müller


normen.mueller
Joined: 2008-10-31,
User offline. Last seen 3 years 8 weeks ago.
Re: Design question regarding parameterized types and type cons

On Jan 15, 2010, at 1:56 PM, Stefan Langer wrote:

> Just rechecked and Seq is covariant at least in 2.7.7

So, again ;), why doesn't it work then?

> 2010/1/14 Normen Müller
> I still struggling with my design :(
>
> I guess I could bypass the view bound issue, but why doesn't the
> following compile:
> (Sorry for posting to the same thread, but I don't exactly know how
> to name the new one regarding the compiler error)
>
> import scala.xml.{Node, MetaData}
>
> //not sure if covariance is needed here
> case class Spec[+T](val cs: Seq[T])
>
> trait System[-T] {
> def spec[S <: T](l: T): Spec[S]
> }
>
> object Test {
> val s = new System[Node] {
> def spec[S <: Node](n: Node) = {
> n match {
> case Node(l, as, cs@_*) => Spec(cs) // doesn't compile!?
> }
> }
> }
> }
>
> Why is Seq[S] not a subtype of Seq[Node]? Or, what am I missing
> here???
>
> Cheers,
> --
> Normen Müller
>
>
>
>
> Cheers,
> --
> Normen Müller
>
>

Cheers,
--
Normen Müller

Michal Politowski 2
Joined: 2009-09-15,
User offline. Last seen 42 years 45 weeks ago.
Re: Design question regarding parameterized types and type cons

On Thu, 14 Jan 2010 17:09:31 +0100, Normen Müller wrote:
> He,
>
> I still struggling with my design :(
>
> I guess I could bypass the view bound issue, but why doesn't the following compile:
> (Sorry for posting to the same thread, but I don't exactly know how to name the new one regarding the compiler error)
>
> import scala.xml.{Node, MetaData}
>
> //not sure if covariance is needed here
> case class Spec[+T](val cs: Seq[T])
>
> trait System[-T] {
> def spec[S <: T](l: T): Spec[S]
> }
>
> object Test {
> val s = new System[Node] {
> def spec[S <: Node](n: Node) = {
> n match {
> case Node(l, as, cs@_*) => Spec(cs) // doesn't compile!?
> }
> }
> }
> }
>
> Why is Seq[S] not a subtype of Seq[Node]? Or, what am I missing here???

The error message is:
error: type mismatch;
found : Seq[scala.xml.Node]
required: Seq[S]
case Node(l, as, cs@_*) => Spec(cs)

So actually this is a reverse problem: Seq[Node] is not a subtype of Seq[S].

You want to return Spec[S], so you must pass a Seq[S] to the constructor
(or a subtype, since Spec is covariant in T), but you actually have a Seq[Node], a supertype.

boisvert
Joined: 2009-11-11,
User offline. Last seen 38 weeks 5 days ago.
Re: Design question regarding parameterized types and type con
It doesn't work because S is not fixed to Node in,

def spec[S <: Node](n: Node): Sesq[S]

it can be any subtype.  Think about the case where the caller does,

spec[Element](someNode)

your code would return Nodes that are possibly not Elements -- a violation of the contract.

So you're going to have to find a different way to express what you want.  I'm not clear on what you're trying to achieve but if you can provide a few examples, I think we can help you find the proper type arrangement.

alex


On Fri, Jan 15, 2010 at 5:25 AM, Normen Müller <normen.mueller@googlemail.com> wrote:
On Jan 15, 2010, at 1:56 PM, Stefan Langer wrote:

Just rechecked and Seq is covariant at least in 2.7.7

So, again ;), why doesn't it work then?

2010/1/14 Normen Müller <normen.mueller@googlemail.com>
I still struggling with my design :(

I guess I could bypass the view bound issue, but why doesn't the following compile:
(Sorry for posting to the same thread, but I don't exactly know how to name the new one regarding the compiler error)

import scala.xml.{Node, MetaData}

//not sure if covariance is needed here
case class Spec[+T](val cs: Seq[T])

trait System[-T] {
 def spec[S <: T](l: T): Spec[S]
}

object Test {
 val s = new System[Node] {
 def spec[S <: Node](n: Node) = {
   n match {
     case Node(l, as, cs@_*) => Spec(cs) // doesn't compile!?
   }
 }
 }
}

Why is Seq[S] not a subtype of Seq[Node]?  Or, what am I missing here???

Cheers,
--
Normen Müller




Cheers,
--
Normen Müller




Cheers,
--
Normen Müller


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