2016-09-25 24 views
1

我是相當新的Scala和我一直在考慮這個功能如何在Scala中調用這個maptree函數?

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

你離這樣一個例子不算太遠。添加你的類型 - 'Leaf','Node'和'Tree'。 –

回答

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

謝謝!!!!!! – Vandexel

+0

這也解決了類型推斷問題:'def add_n(t:Tree [Int],n:Int):Tree [Int] = map_tree((x:Int)=> x + n)(t) 'n'是一個Int,但該信息和加操作數不足以推斷'x'的類型。所以'x'的類型必須是明確的。 – Samar

2

只是對@ Chris_Martin的答案添加,這裏是類型推斷問題的精確解釋

  • 對於拉姆達在不提供參數類型的情況下進行類型檢查,lambda的預期類型必須已知。例如,你可以寫val f: Int => Int = _ + 1但不val f = _ + 1即使你使用f以後作爲Int => Int(Scala的類型推斷是當地)。

  • 在方法調用參數列表是獨立型檢查,由左到右。所以要檢查map_tree(t => t+n)(t),斯卡拉首先檢查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),推斷爲IntA因此能夠正確地稍後鍵入拉姆達。