我对Scala很新,我已经获得了这个功能
$
这是我的Tree类以及Leaf和Node定义
def map_tree[A,B](f: A => B)(tree: Tree[A]): Tree[B] =
tree match {
case Leaf(value) => Leaf(f (value))
case Node(value , l, r) => Node(f (value), map_tree (f) (l), map_tree (f) (r))
}
如何在另一个函数中调用此map_tree函数?
例如,如果我有这个功能
abstract class Tree[+A]
case class Leaf[A](value: A) extends Tree[A]
case class Node[A](value: A, left: Tree[A], right: Tree[A]) extends Tree[A]
如何在其中调用map_tree以使其将n添加到树中的每个元素?
def add_n(t: Tree[Int], n: Int) : Tree[Int] =
我试过这样称呼它:
def add_n(t: Tree[Int], n: Int) : Tree[Int] =
map_tree(what do I input here)?
但它告诉我"无效的参数类型"。我认为这不是输入应该是什么,但我不确定我应该在map_tree的第一个括号中输入什么
答案 0 :(得分:3)
我收到一条不同的错误消息(在Scala 2.11.8中):
scala> abstract class Tree[+A]
defined class Tree
scala> case class Leaf[A](value: A) extends Tree[A]
defined class Leaf
scala> case class Node[A](value: A, left: Tree[A], right: Tree[A]) extends Tree[A]
defined class Node
scala> def map_tree[A,B](f: A => B)(tree: Tree[A]): Tree[B] =
| tree match {
| case Leaf(value) => Leaf(f (value))
| case Node(value , l, r) => Node(f (value), map_tree (f) (l), map_tree (f) (r))
| }
map_tree: [A, B](f: A => B)(tree: Tree[A])Tree[B]
scala> def add_n(t: Tree[Int], n: Int) : Tree[Int] = map_tree( t => t+n)(t)
<console>:17: error: missing parameter type
def add_n(t: Tree[Int], n: Int) : Tree[Int] = map_tree( t => t+n)(t)
无论如何,这只是类型推断使你失败,有时会发生。如果你明确地给它类型args它可以正常工作:
scala> def add_n(t: Tree[Int], n: Int): Tree[Int] = map_tree[Int, Int](t => t + n)(t)
add_n: (t: Tree[Int], n: Int)Tree[Int]
答案 1 :(得分:2)
只是添加@ Chris_Martin的答案,这是类型推断问题的精确解释:
对于要在不提供参数类型的情况下进行类型检查的lambda,必须知道lambda的预期类型。例如,即使您稍后使用val f: Int => Int = _ + 1
作为val f = _ + 1
(Scala的类型推断是 local ),您也可以写f
但不能Int => Int
。
方法调用中的参数列表从左到右独立地进行类型检查。因此,要检查map_tree(t => t+n)(t)
,Scala首先检查map_tree(t => t+n)
,但此时尚未确定A
类型参数应该是什么,因此{{1}没有预期的类型} lambda,导致你得到的错误。
<强>解决方案:强>
您可以简单地在t => t+n
中交换参数列表,如:
map_tree
然后您可以像def map_tree[A,B](tree: Tree[A])(f: A => B): Tree[B] = ...
一样调用它,因为Scala会首先键入check map_tree(t)(t => t+n)
,为map_tree(t)
推断Int
,从而能够在以后正确输入lambda上。