如何在Scala中调用此maptree函数?

时间:2016-09-25 06:50:04

标签: scala currying

我对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的第一个括号中输入什么

2 个答案:

答案 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上。