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

Looking for type help when defining "Parent" and "Child" traits

No replies
Ken McDonald
Joined: 2011-02-13,
User offline. Last seen 42 years 45 weeks ago.
Well, I'm defining my first traits where the typing could put hair on my chest :-). I'm trying to abstract out "Parent" and "Child" traits for a mutable tree structure. One of my several (incorrect) attempts is:
trait Parent[C <: Child[Parent]] { val children: collection.mutable.Buffer[C] = new ArrayBuffer[C]
def indexOf(child: C) = children.indexOf(child)
def insert(at: Int, child: C) { child.removeFromParent children.insert(at, child) child.parent = Some(this) }

def remove(child: C) { val pos = children.indexOf(child) children(pos).parent = None children.remove(pos) }

def length = children.length
def +=(child: C) { insert(length, child) }}
trait Child[P <: Parent[Child]] { var parent: Option[P] = None
def removeFromParent { parent match { case None => case Some(p) => p.remove(this) } }
def replaceWith(other: Child[P]) { val p = this.parent.get val pos = p.indexOf(this) //TODO inefficient this.removeFromParent p.insert(pos, other) }}
This has the advantage that it only generated 4 compile-time errors. It has the disadvantage that resolving those errors would require defining infinitely recursive types, and I can't type that long, plus it would probably exhaust the memory on my system :-). And it probably still wouldn't be correct.
What I want to be able to do is something like:
trait LayoutElement {    def repaint;}

class ContainerLayout extends LayoutElement with Parent[LayoutElement] {
    def bubble ... 
    def repaint: for (c <- children) c.repaint}

trait LeafLayout extends LayoutElement with Child[ContainerLayout] {    def keyPress { parent.bubble }} 

Well, that may not be quite correct, but hopefully you get the idea. So it's similar to many collection classes, the main difference being that a Child needs to know about both its parent's type, and the type of the class it is mixed in with, and similarly a Parent has to know about its childrens' types and the type of the class it's mixed into.
However, the Scala type system is so rich that I'm not quite sure how to proceed. I've been looking in "Prog in Scala" and at some relevant posts on the lists, and will probably manage to hack something together in time, but if you'd care to comment on this, it'd help me get things done faster and probably quite a bit better too.
Thanks,Ken

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