2012-10-29 91 views
15

我寫了下面斯卡拉匿名函數缺少參數類型的錯誤

def mapFun[T, U](xs: List[T], f: T => U): List[U] = (xs foldRight List[U]())(f(_)::_) 

,當我做了

def f(x: Int):Int=x*x 
mapFun(List(1,2,3), f) 

它工作得很好。但是,我真的想做以下工作

mapFun(List(1,2,3), x=>x*x) 

它抱怨「缺少參數類型」。我知道我可以使用currying,但有沒有辦法仍然使用匿名函數來進行非curring def我上面的?

回答

23

在我看來,因爲「f」與「xs」在相同的參數列表中,所以您需要提供一些關於x的類型的信息,以便編譯器可以解決它。

在你的情況,這將工作:

mapFun(List(1,2,3) , (x: Int) => x * x) 

你看我怎麼通知編譯器,x是一個詮釋?

你可以做的一個「竅門」是咖喱f。如果你不知道什麼是鑽營檢查了這一點:http://www.codecommit.com/blog/scala/function-currying-in-scala

您將結束與這樣的mapFun:

def mapFun[T, U](xs: List[T])(f: T => U): List[U] = 
    (xs foldRight List[U]())(f(_)::_) 

,這將工作:

mapFun(List(1,2,3))(x => x * x) 

在最後調用時,編譯器檢查第一個參數列表時解析x的類型。

編輯:

正如多米尼克指出的那樣,你可以告訴編譯器,你的類型。導致:

mapFun[Int, Int](List(1,2,3), x => x * x) 

乾杯!

+0

還可以指定類型PARAMS像這樣:'mapFun [INT,INT](列表(1,2,3)中,x => X * X)' –

+1

噢,當然。你總是可以明確地告訴你的類型是什麼。感謝Dominic。 – wleao

+0

我試着在List類型上使用Pimp我的庫模式實現他的功能,但無法讓類型工作。可能? –

14

你正在運行到這裏Scala的類型系統的限制是類型信息來自全國各地參數組左至右流動,從左邊的參數組內不流到右

這意味着通過提供List[Int]來指定類型參數T將不會將該信息提供給組中的其他參數,如f。這導致缺少參數類型錯誤。但是如果f是下一個參數組的一部分,它將提供給f。這就是爲什麼curried函數方法有效。

即如果定義這樣的:

def mapFun[T, U](xs: List[T])(f: T => U): List[U] = (xs foldRight List[U]())(f(_)::_) 

類型參數T您第一參數組中的定義:作爲(xs: List[T])Int將提供到下一個參數組:(f: T => U)。所以現在你不必在呼叫站點明確指定T

+0

想了解更多關於這個限制的知識,有沒有關於它在規範中寫的東西? – nornagon