2014-03-13 59 views
1

斯卡拉有一個內置FunctionN性狀高達Function22。有相應的PartialFunctionN似乎很自然。那爲什麼scala沒有它?有沒有一個固有的原因,爲什麼它不包含在scala中?爲什麼scala沒有內置的PartialFunctionN?

很容易,我自己實現了接近PartialFunctionN的東西。我們當然可以定義很明顯:

type PartialFunction2[-T1,-T2,+R] = PartialFunction[Tuple2[T1,T2],R] 

,但返回的類型實際上是:

scala> val f: PartialFunction2[Int,Int,Int] = {case (2,3) => 8; case (3,2) => 9} 
f: PartialFunction2[Int,Int,Int] = <function1> 

scala> f(2,3) 
res0: Int = 8 

scala> f(2,7) 
scala.MatchError: (2,7) (of class scala.Tuple2$mcII$sp) ... 

這是令人困惑,因爲它看起來像一個<function2>而不是<function1>

另一種方法是定義PartialFunctionN遞歸:

type PartialFunction2[-T1,-T2,+R] = PartialFunction[T1,PartialFunction[T2,R]] 

但使用率不會像漂亮,乾淨像以前的例子中,我們仍然可以得到<function1>

scala> val g: PartialFunction2[String,String,String] = { 
case "x" => {case "y" => "male"; case "x" => "female"} 
} 
g: PartialFunction2[String,String,String] = <function1> 

scala> g("x")("y") 
res0: String = male 

scala> g("x")("x") 
res1: String = female 

scala> g("y")("x") 
scala.MatchError: y (of class java.lang.String) ... 

所以,基本上,我很有興趣知道是否有一個很好的理由,爲什麼斯卡拉沒有PartialFunctionN內置,作爲獎金,我也想知道是否有辦法模仿預期的功能,並獲取而不是<function1>作爲返回類型。

+0

我認爲當你調用f(2,3)時,你真的調用f((2,3))。也許你可以去咖喱... –

+1

當然它f((2,3))。很像其他任何有一個參數的函數。 'f:Function1 [Int,Int]'可以被稱爲'f(1)'或'f 1'。所以你是對的,當然! :) –

+0

是啊,我注意到你已經嘗試了一種通過遞歸鍵入的類型... –

回答

1

,並獲得代替<function1>作爲返回類型

f: PartialFunction2[Int,Int,Int] = <function1> 

類型PartialFunction2[Int,Int,Int],就像你想要的。 <function1>是調用toString以顯示REPL中的函數的結果。請注意,給定您的定義PartialFunction2[Int,Int,Int]PartialFunction,因此Function1,而不是Function2。你可以定義

trait PartialFunction2[-T1,-T2,+R] extends Function2[T1,T2,R] { 
    def isDefinedAt(x: T1, y: T2): Boolean 
} 

,但你不會得到任何好的語法(你可以從PartialFunction[Tuple2[T1,T2],R]添加一個隱含的converstion到PartialFunction2[T1,T2,R]雖然)。

我是intrested知道如果有一個很好的理由,爲什麼斯卡拉沒有內置PartialFunctionN

如果您在標準庫中有PartialFunction2,它是由您所需的創建語法,那麼你必須有一個元組的PartialFunction一些不同的語法。已經夠複雜了。

+0

我不認爲語法是問題。我希望編譯器選擇更明確的形式。很像它已經在做。例如:'object Foo {def f(t:Tuple2 [Int,Int]):Unit = println(s「得到了TUPLE $ {t._1}和$ {t._2}!」); def f(i:Int,j:Int):Unit = println(s「got 2 regular int:$ i and $ j。」)}'並嘗試:'Foo.f(2,3)'。你會得到:'有2個常規整數:2和3',當然,如果有人同時定義了'PartialFunctionN'和'PartialFunction [TupleN,R]',那麼在調用'pf(x ,y,...)'它應該選擇'PartialFunctionN'實現。 –

+0

我不是在談論重載,而是關於定義語法。如果你寫了'val f = {case(x:Int,y:Int)=> x + y}'(目前這是非法的,但是這個改變會有意義),如果它定義了'PartialFunction2 [Int,Int,Int ]'或'PartialFunction [(Int,Int),Int]'? –

+0

這是句法糖。如果它真的含糊不清(這意味着編譯器無法自行推斷出預期的類型),那麼我猜編譯應該會失敗。 (PartialFunction [Tuple2 [Int,Int],Int] {case(1,2)=> 3}或PartialFunction2 [Int,Int,Int] {case(1, 2)=> 3}' –

相關問題