[英]Scala local type inference underscore notation
通過研究“ Scala中的函數式編程”,我想知道為什么以下代碼會給出缺少的參數類型錯誤。
定義了以下樹數據結構:
sealed trait Tree[+A]
case class Leaf[A](value: A) extends Tree[A]
case class Branch[A](left: Tree[A], right: Tree[A]) extends Tree[A]
以及以下方法:
object Tree {
def fold[A,B](t: Tree[A])(z: A => B)(f: (B,B) => B): B = t match {
case Leaf(v) => z(v)
case Branch(l,r) => f(fold(l)(z)(f), fold(r)(z)(f)) }
def size2[A](t: Tree[A]): Int = fold(t)((_) => 1)(_ + _ + 1)
def maximum2(t: Tree[Int]): Int = fold(t)((a) => a)(_ max _)
def depth2[A](t: Tree[A]): Int = fold(t)((_) => 0)(1 + (_ max _))
}
該方法size2個和maximum2編譯就好了,但深度2不意味着在最后一個函數的類型。
編寫方法如下:
def depth2[A](t: Tree[A]): Int = fold(t)((_) => 0)((a,b) => 1 + (a max b))
使它編譯就好了。
問:為什么Scala不能在帶下划線符號的第一種方法上推斷類型,而在第二種方法上有推斷呢? 是什么使其他方法可以正常編譯?
謝謝你的幫助。
標尺版本:2.11.4
1 + (_ max _)
擴展為1 + ((a, b) => a max b)
,這會向1添加一個函數。如果指定類型,則會出現另一個錯誤:
<console>:22: error: overloaded method value + with alternatives:
(x: Double)Double <and>
(x: Float)Float <and>
(x: Long)Long <and>
(x: Int)Int <and>
(x: Char)Int <and>
(x: Short)Int <and>
(x: Byte)Int <and>
(x: String)String
cannot be applied to ((Int, Int) => Int)
def depth2[A](t: Tree[A]): Int = fold(t)((_) => 0)(1 + ((_: Int) max (_: Int)))
如您所見,您需要明確地放置參數
(a,b) => 1 + (a max b)
或跳過原諒
1 + _ max _
您實際上無法在此處執行此操作,因為它可以像您說的那樣工作
(a,b) => (1 + a) max b
原來,在第一個方法中刪除括號,刪除所有編譯錯誤,如下所示:
def depth2[A](t: Tree[A]): Int = fold(t)((_) => 0)((a,b) => 1 + a max b)
因此,下划線符號似乎總是選擇最接近的范圍來推斷類型。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.