Have a look at these two simple traits:
trait TreeNode1[S] {
def subNodes: List[S]
}
trait TreeNode2 {
def subNodes: List[this.type]
}
(Not best naming, renamed them just to be brief.)
TreeNode1
defines a tree node with its children access, pointing their type S
.
TreeNode2
defines the same, but its children have the same type as the class the current trait is mixed in (another words, tree node with uniform subnodes).
In theory TreeNode2
is a particular case of TreeNode1
:
trait TreeNode2 extends TreeNode1[this.type] {...}
But Scala will not compile TreeNode2
with such an extension, because this.type
can not be used in such way, although there are no any inconsistencies with its working in runtime.
How can I get around this situation? Or Scala do not offer such poorly used mechanism?
The reason I need this construction is the following:
I have another trait that requires TreeNode1
to be mixed in. I also have some class that mixes TreeNode1
with quite another children type. But I also have several classes which have the same type as they are:
class SomeTreeNode extends TreeNode1[SomeTreeNode]
So it will look prettier if I use TreeNode2
for it:
class SomeTreeNode extends TreeNode2
Implementing the same logic. But for using TreeNode2
should be a case of TreeNode1
, which it actually is, but Scala doesn't agree with me.
PS At least it is wondering as theoretical question about Scala, not for a wide practical use.
its children have the same type as the class the current trait is mixed
No. This is a common misunderstanding. this.type
is the singleton type of this
; ie the type whose only two values are this
and null
. All children of a TreeNode2
instance must be the same instance.
To answer the other part of your question, one option is to make S
a type member instead of a type parameter:
trait TreeNode1 {
type S
def subNodes: List[S]
}
object TreeNode1 {
// use TreeNode1.Aux[S] where you had TreeNode1[S] originally
type Aux[T] = TreeNode1 { type S = T }
}
trait TreeNode2 {
type S = this.type // not really what you want
def subNodes: List[this.type]
}
(so-called Aux
pattern), but whether this works for you depends on how they are used.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.