2013-09-27 27 views
1

我才意識到,我的泛型方法:鑽營泛型方法/功能沒有鬆動的泛型參數

def method[A](list: List[A]): A = { ... } 

將導致非通用功能型

val methodFun = method _ 
-> methodFun : (scala.List[Nothing]) => Nothing 

討好它,而不是保持它的泛型類型。是否有可能保留泛型類型信息?我發現我可以通過設置

val methodFun = method[String] _ 
-> methodFun : (scala.List[String]) => String 

定義一些明確的類型,例如String但是這不是我真正想要的東西。我目前傾向於使用原始類型來避免這個問題(只要我知道如何)或者是否有更好的解決方案?

感謝您的幫助!

PS:爲什麼我要做到這一點:

def method1[A](list: List[A]): A = { ... } 
def method2[A](element: A): Int = { ... } 
// This will not cause a compiler error as stated before 
// but this will result in (List[Nothing]) => Int 
// but I want a (List[A]) => Int 
val composedFun = method1 _ andThen method2 
// The next line is possible 
// but it gives me a (List[String]) => Int 
val composedFunNonGeneric = method1[String] _ andThen method2[String] 
+0

它沒有意義,因爲寫的,但在一般情況下,它是有道理的。要麼因爲有多個參數,要麼因爲我想編寫函數。 –

+1

忽略我的第一個評論:這不是curring,它是eta-expansion。 ;)我看到它的感覺。 – itsbruce

回答

4

讓我們來看看你的例子:

def method1[A](list: List[A]): A = { ... } 
def method2[A](element: A): String = { ... } 
// The next line will cause a compiler error 
val composed = method1 _ andThen method2 

首先,不給我一個編譯器錯誤,而是有你提到的太具體類型(List[Nothing]=>String)

如果您想了解爲什麼這樣做不起作用,請考慮這種方式:您對composed期待的類型是什麼?我想你想要這樣的東西List[A]=>String。然而,composedval,而不是一個def(即它是一個函數對象,而不是一個方法實例)。對象實例必須具有特定的類型。如果你想在這裏使用一個泛型類型,那麼你必須將這個val包含在一個具有泛型類型的類定義中,但即使如此,泛型類型也將被限制爲爲該類的每個特定實例指定/推斷的類型。

總之,如果你想撰寫方法和保持類型的參數,你需要用def代替人工撰寫他們並宣佈它:

def composed[A](list: List[A]): String = method2(method1(list))