2016-03-01 129 views
3

我重寫了一系列的斯卡拉Haskell函數,跑進我似乎無法解釋缺少參數類型

的錯誤如下編譯錯誤:

missing parameter type 
    def group[A](xs: List[A]): List[List[A]] = groupBy((a, b) => a == b, xs) 
                 ^
missing parameter type 
    def group[A](xs: List[A]): List[List[A]] = groupBy((a, b) => a == b, xs) 
                 ^

代碼如下:

object Stuff { 
    def main(args: Array[String]): Unit = { 
    val lst = List(1, 1, 1, 1, 2, 2, 2, 3, 4, 4, 5, 6, 7) 
    println(group(lst)) 
    } 

    def group[A](xs: List[A]): List[List[A]] = groupBy((a, b) => a == b, xs) 
    def groupBy[A](fun: (A, A) => Boolean, input: List[A]): List[List[A]] = // stuff 
} 

我根本不知道這裏發生了什麼,爲什麼它抱怨缺少參數類型。據我所見,一切都是定義的

回答

6

它將編譯,如果你提供的groupBy調用點明確的泛型類型參數:

def group[A](xs: List[A]): List[List[A]] = groupBy[A]((a, b) => a == b, xs) 

對於爲什麼Scala的類型推斷失敗作出解釋見this post這個案例。

如果你寫groupBy咖喱參數列表類型的信息應正確推斷:

def group[A](xs: List[A]): List[List[A]] = groupBy(xs)((a, b) => a == b) 

def groupBy[A](input: List[A])(fun: (A, A) => Boolean): List[List[A]] = input match { 
    case Nil => Nil 
    case (x::xs) => 
    val (ys, zs) = span(fun.curried(x), xs) 
    (x::ys)::groupBy(zs)(fun) 
}  
2

這似乎是類型推理系統的限制。你可以嘗試以下方法:

def group[A](xs: List[A]): List[List[A]] = groupBy((a: A, b: A) => a == b, xs) 
2

你的功能(a, b) => a == b沒有指定其參數的類型。您可以輕鬆地將其固定爲:

def group[A](xs: List[A]): List[List[A]] = groupBy((a: A, b: A) => a == b, xs) 

def group[A](xs: List[A]): List[List[A]] = groupBy[A]((a, b) => a == b, xs) 

編輯:

另一個答案已經指出,如果您切換參數的地方,咖喱他們會工作。是的,因爲那麼第二個參數會從第一個參數推斷出來。請注意,第二個參數列表可以從第一個參數列表中學習,但如果它們是一個參數列表中的兩個參數,那麼這是不可能的(它在Scala規範中),所以我們需要currying。但是,我認爲簡單地表示類型而不是切換參數和咖喱功能會更容易。簡化了不必要的複雜問題。