我正在练习#34; Scala for the Impatient",Chapter 14,Q8:
基本上我需要创建一个接收运算符和节点的函数(利用模式匹配),并输出操作的结果。例如。节点(+,Node(*,Leaf(2),Leaf(3))Leaf(1))应输出7。
以下是一些给定的类:
sealed abstract class BinaryTree
case class Leaf(value: Int) extends BinaryTree
所以我创建了一个Node类,但是我很难弄清楚如何传入运算符。
case class Node(op: Function (what goes here?) , leaves: BinaryTree*) extends BinaryTree
我想像这样使用模式匹配:
tree match {
case Node(op, leaves @ _*) => op match {
case op : Function => leaves.reduceLeft(_ op _)
}
case leaf: Leaf => leaf.value
但是
case op : Function => leaves.reduceLeft(_ op _)
部分是错误的。我不知道如何使用在Node类中传递的运算符。我在这里做错了什么?
答案 0 :(得分:3)
我假设运算符将始终是二进制因此,我们所谓的BinaryTree将至少有两个操作数:
trait BinaryTree
case class Leaf(value: Int) extends BinaryTree
case class Node(op: Function2[Int, Int, Int], l1: BinaryTree*) extends BinaryTree
object Operators {
val + = (a: Int, b: Int) => a + b
val * = (a: Int, b: Int) => a * b
}
def f(tree: BinaryTree): Int = {
tree match {
case n: Node => n.l1.map(f).reduceLeft((r,c) => n.op(r,c))
case leaf: Leaf => leaf.value
}
}
一些测试结果:
简单的一个:
scala> f(Node(Operators.*,Leaf(4),Leaf(2),Leaf(3)))
res4: Int = 24
scala> f(Node(Operators.+,
Node(Operators.*, Leaf(2), Leaf(1), Leaf(4), Leaf(5)), Leaf(6)))
res5: Int = 46
scala> f(Node(Operators.+,
Node(Operators.*, Leaf(2), Leaf(1), Leaf(4), Leaf(5)),
Node(Operators.+,Leaf(9),Leaf(9)), Leaf(6)))
res6: Int = 64
相当复杂:
scala> f(Node(Operators.+,
Node(Operators.*, Leaf(2), Leaf(1),
Node(Operators.* ,Leaf(4), Leaf(5) ,Leaf(2))),
Node(Operators.+,Leaf(9),Leaf(9)), Leaf(6),
Node(Operators.*, Leaf(2), Leaf(2))))
res7: Int = 108
答案 1 :(得分:2)
它有更优雅的解决方案,但因为你想要它与模式匹配:
sealed abstract class BinaryTree
case class Leaf(value: Int) extends BinaryTree
case class Node(op: (Int, Int) => Int , leaves: BinaryTree*) extends BinaryTree
def calc(tree: BinaryTree): Int = tree match {
case Leaf(v) => v
case Node(op, h, leaves @ _*) => leaves.foldLeft(calc(h))((a,b) => op(a,calc(b)))
}
object Operators {
def +(a: Int, b: Int): Int = a + b
def *(a: Int, b: Int): Int = a * b
}
val tree = Node(Operators.+, Node(Operators.*, Leaf(9), Leaf(3)), Leaf(1))
calc(tree)