- About Scala
- Documentation
- Code Examples
- Software
- Scala Developers
Another generics mystery
Fri, 2010-01-22, 05:37
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-
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-
>