我如何在 Scala 中调用这个 maptree 函数?

How do I call this maptree function in Scala?

我是 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))
}

这是我的树 class 以及叶子和节点定义

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 函数?

例如如果我有这个功能

def add_n(t: Tree[Int], n: Int) : Tree[Int] =

如何在其中调用 map_tree 使其将 n 添加到树中的每个元素?

def add_n(t: Tree[Int], n: Int) : Tree[Int] =
    map_tree(what do I input here)?

我试过这样称呼它:

  map_tree( t => t+n)(t)

但它告诉我 "Invalid parameter type"。我认为这不是输入应该是什么,但我不确定我应该在 map_tree

的第一个括号中输入什么

我收到一条不同的错误消息(在 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]

补充一下@Chris_Martin的回答,这里是类型推断问题的精确解释

  • 要在不提供参数类型的情况下对 lambda 进行类型检查,必须知道 lambda 的预期类型。例如,你可以写 val f: Int => Int = _ + 1 而不是 val f = _ + 1 即使你稍后使用 f 作为 Int => Int (Scala 的类型推断是 local).

  • 方法调用中的参数列表从左到右独立进行类型检查。所以要检查 map_tree(t => t+n)(t),Scala 首先检查 map_tree(t => t+n),但此时它还没有决定 A 类型参数应该是什么,所以 [=18= 没有预期的类型] lambda,导致你得到的错误。

解法:

您可以简单地交换 map_tree 中的参数列表,如:

def map_tree[A,B](tree: Tree[A])(f: A => B): Tree[B] = ...

然后你可以像 map_tree(t)(t => t+n) 一样调用它,因为 Scala 将首先输入检查 map_tree(t),为 A 推断 Int,从而能够输入 lambda稍后正确。