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

Another generics mystery

1 reply
Sciss
Joined: 2008-12-17,
User offline. Last seen 28 weeks 5 days ago.

hi,

i am having another tricky generics problem. actually it looks like a bug to me, maybe it's just that the compiler error message is badly put.

Welcome to Scala version 2.8.0.r20552-b20100117020202 (Java HotSpot(TM) Client VM, Java 1.6.0_17).
Type in expressions to have them evaluated.
Type :help for more information.

scala> trait Stake
defined trait Stake

scala> trait Trail[ T <: Stake ]
defined trait Trail

scala> trait Track[ T <: Stake ] {
| def trail: Trail[ T ]
| }
defined trait Track

scala> trait TrailView[ T <: Stake ] {
| def editor: Option[ TrailViewEditor[ T ]]
| def selectedStakes: Set[ T ]
| def trail: Trail[ T ]
| }; trait TrailViewEditor[ T <: Stake ] {
| def editDeselect( stakes: T* )
| def view: TrailView[ T ]
| }
defined trait TrailView
defined trait TrailViewEditor

scala> trait TracksView {
| def tracks: Seq[ Track[ _ <: Stake ]]
| def trailView[ T <: Stake ]( t: Track[ T ]) : Option[ TrailView[ T ]]
| def forEachTrailViewEditor( f: TrailViewEditor[ _ <: Stake ] => Unit ) {
| tracks.foreach( t => {
| trailView( t ).foreach( tv => {
| tv.editor.foreach( ed => f( ed ))
| })
| })
| }
| }
defined trait TracksView

scala> def test( tt: TracksView ) {
| tt.forEachTrailViewEditor( ed => {
| val stakes = ed.view.selectedStakes
| ed.editDeselect( stakes.toList: _* )
| })
| }
:13: error: type mismatch;
found : List[Stake]
required: Seq[_$2] where type _$2 <: Stake
ed.editDeselect( stakes.toList: _* )
^

how can this happen? strange this is, if i accidentally try to give in the Set to editDeselect, so omitting the toList, i get

scala> def test( tt: TracksView ) {
| tt.forEachTrailViewEditor( ed => {
| val stakes = ed.view.selectedStakes
| ed.editDeselect( stakes: _* )
| })
| }
:13: error: type mismatch;
found : scala.collection.immutable.Set[_$2(in value $anonfun)] where type _$2(in value $anonfun) <: Stake
required: Seq[(some other)_$2(in value $anonfun)] where type (some other)_$2(in value $anonfun) <: Stake
ed.editDeselect( stakes: _* )
^

so the type parameter of stakes is definitely _ <: Stake, not Stake. or maybe i'm doing something completely wrong here, don't know.

any help is appreciated!

thanks, -sciss-

Sciss
Joined: 2008-12-17,
User offline. Last seen 28 weeks 5 days ago.
Re: Another generics mystery

so, i think the problem is that no appropriate types can be defined for the passed in function to method forEachTrailViewEditor... because if instead of

tt.forEachTrailViewEditor( ed => {
val stakes = ed.view.selectedStakes
ed.editDeselect( stakes.toList: _* )
})

i "paste" the method body inline:

tt.tracks.foreach( t =>
tt.trailView( t ).foreach( tv => {
tv.editor.foreach( ed2 => {
val stakes = ed2.view.selectedStakes
ed2.editDeselect( stakes.toList: _* )
})

it compiles fine.... so the only problem left is the higher-generics map... i will try to create a subclass as seth suggests.

ciao, -sciss-

Am 22.01.2010 um 04:37 schrieb Sciss:

> hi,
>
> i am having another tricky generics problem. actually it looks like a bug to me, maybe it's just that the compiler error message is badly put.
>
> Welcome to Scala version 2.8.0.r20552-b20100117020202 (Java HotSpot(TM) Client VM, Java 1.6.0_17).
> Type in expressions to have them evaluated.
> Type :help for more information.
>
> scala> trait Stake
> defined trait Stake
>
> scala> trait Trail[ T <: Stake ]
> defined trait Trail
>
> scala> trait Track[ T <: Stake ] {
> | def trail: Trail[ T ]
> | }
> defined trait Track
>
> scala> trait TrailView[ T <: Stake ] {
> | def editor: Option[ TrailViewEditor[ T ]]
> | def selectedStakes: Set[ T ]
> | def trail: Trail[ T ]
> | }; trait TrailViewEditor[ T <: Stake ] {
> | def editDeselect( stakes: T* )
> | def view: TrailView[ T ]
> | }
> defined trait TrailView
> defined trait TrailViewEditor
>
> scala> trait TracksView {
> | def tracks: Seq[ Track[ _ <: Stake ]]
> | def trailView[ T <: Stake ]( t: Track[ T ]) : Option[ TrailView[ T ]]
> | def forEachTrailViewEditor( f: TrailViewEditor[ _ <: Stake ] => Unit ) {
> | tracks.foreach( t => {
> | trailView( t ).foreach( tv => {
> | tv.editor.foreach( ed => f( ed ))
> | })
> | })
> | }
> | }
> defined trait TracksView
>
> scala> def test( tt: TracksView ) {
> | tt.forEachTrailViewEditor( ed => {
> | val stakes = ed.view.selectedStakes
> | ed.editDeselect( stakes.toList: _* )
> | })
> | }
> :13: error: type mismatch;
> found : List[Stake]
> required: Seq[_$2] where type _$2 <: Stake
> ed.editDeselect( stakes.toList: _* )
> ^
>
> how can this happen? strange this is, if i accidentally try to give in the Set to editDeselect, so omitting the toList, i get
>
> scala> def test( tt: TracksView ) {
> | tt.forEachTrailViewEditor( ed => {
> | val stakes = ed.view.selectedStakes
> | ed.editDeselect( stakes: _* )
> | })
> | }
> :13: error: type mismatch;
> found : scala.collection.immutable.Set[_$2(in value $anonfun)] where type _$2(in value $anonfun) <: Stake
> required: Seq[(some other)_$2(in value $anonfun)] where type (some other)_$2(in value $anonfun) <: Stake
> ed.editDeselect( stakes: _* )
> ^
>
> so the type parameter of stakes is definitely _ <: Stake, not Stake. or maybe i'm doing something completely wrong here, don't know.
>
> any help is appreciated!
>
> thanks, -sciss-
>

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