2016-09-25 3 views
1

Я довольно новыми для Scala и мне дали эту функциюКак я могу назвать эту функцию maptree в 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)) 
} 

Вот мой класс Дерево и определения листьев и узлов

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 в нем, чтобы вызвать его, чтобы добавить п к каждому элементу в дереве?

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

Я попытался назвать это так:

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

Но это говорит мне "Неверный тип параметра". Я думаю, что это не то, что вход должен быть, но я не уверен, что я должен войти в первых скобках в map_tree

+2

Пожалуйста, создайте [MCVE] вашей проблемы. –

+0

Хорошо, я попытался это сделать! – Vandexel

+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) 

Во всяком случае, это только вывод типа, который вас не устраивает, как это бывает иногда. Он отлично работает, если вы даете ему арг типа явно:

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] 
+0

Спасибо !!!!!! – Vandexel

+0

Это также решает проблему вывода типа: 'def add_n (t: Tree [Int], n: Int): Tree [Int] = map_tree ((x: Int) => x + n) (t)' Компилятор знает что 'n' - это Int, но этот info и дополнительный операнд недостаточно, чтобы вывести тип' x'. Таким образом, тип 'x' должен быть явным. – Samar

2

Просто добавить на @ Chris_Martin отвечает, вот точное объяснение проблемы вывода типов:

  • Для лямбды для проверки типа без предоставления типов параметров ожидаемый тип лямбда должен быть известен. Например, вы можете написать 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, поэтому нет ожидаемого типа для лямбда t => t+n, в результате чего вы получите ошибку.

Решение:

Вы можете просто поменять списки параметров в 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), выведите Int за A и, таким образом, сможете правильно ввести лямбду позже.