Polymorphic scala return type in recursive functions

I have a tree structure:

sealed trait Tree
case class Node(l: Tree, r: Tree) extends Tree
case class Leaf(n: Int) extends Tree

And a function that modifies the tree:

def scale(n: Int, tree: Tree): Tree = tree match {
  case l: Leaf => Leaf(l.n * n)
  case Node(l, r) => Node(scale(n, l), scale(n, r))
}

What should be the signature of the method above in order to return the corresponding subtype of the tree and make the next line a compilation?

scale(100, Leaf(1)).n // DOES NOT COMPILE

The closest answer I've found so far here is about F-Bounded Quantification . But I cannot find a way to apply it to recursive structures such as trees! Any ideas?

+4
source share
2 answers

Besides OOP and overriding, here is another solution:

- Scaler, (T, Int) T, T Tree. Scaler , . -. , Node . , . :)

, :

import language.implicitConversions

sealed trait Tree
case class Node[L <: Tree, R <: Tree](l: L, r: R) extends Tree
case class Leaf(n: Int) extends Tree

trait Scaler[T <: Tree] extends ((T, Int) => T)

object Scaler {
  implicit object scalesLeafs extends Scaler[Leaf] {
    def apply(l: Leaf, s: Int) =
      Leaf(l.n * s)
  }

  implicit def scalesNodes[L <: Tree: Scaler, R <: Tree: Scaler] = new Scaler[Node[L,R]] {
    val ls = implicitly[Scaler[L]]
    val rs = implicitly[Scaler[R]]

    def apply(n: Node[L,R], s: Int) =
      Node(ls(n.l, s), rs(n.r, s))
  }
}

object demo extends App {
  def scale[T <: Tree](t: T, s: Int)(implicit ev: Scaler[T]): T =
    ev(t, s)

  val check1 = scale(Leaf(3), 5)
  val check2 = scale(Node(Leaf(3), Leaf(7)), 5)

  Console println check1.n
  Console println check2.l.n
  Console println check2.r.n
}

. : , , , , , .

+1

scala . ( , ), .

, ( ). - , :

sealed trait Tree {
  def scale(n: Int): Tree
}
case class Node(l: Tree, r: Tree) extends Tree {
  def scale(n: Int): Node = Node(l.scale(n), r.scale(n))
}
case class Leaf(n: Int) extends Tree {
  def scale(m: Int): Leaf = Leaf(n * m) 
}

Leaf(1).scale(100).n // does compile.

, , scale Node Leaf scale Tree.

+2

All Articles