2016-05-03 3 views
2

は、今日のScalaを学び始め、そしてあなたのようなカリー化付加する機能をオーバーロードすることができます場合、私は興味があった:カレーを追加するためのスカラオーバーロード機能?

def add(x: Int, y: Int): Int = x + y 
def add(x: Int)(y: Int): Int = x + y 

しかし、このコードはコンパイルされませんが、私はScalaで過負荷がないことを聞いただけでなく、良いアイデア。

追加アプリケーションを部分的に適用せずにカレート化する方法はありますか?つまり、add(1, 2)add(1)(2)の両方が機能しますか?

  • 引数
  • の数が異なるかaddの両方の定義は同等であるあなたの例では、異なる引数の型(S)

を持っている:それは関数はどちらかがなければならないことが必要だの過負荷のために

答えて

3

問題は、これらのadd機能はJVMの型消去後に見分けがつかないということです。コンパイル時には異なるので、Scalaコンパイラはあなたが呼び出しているものを知ることができます。

これは、引数リストを異なるものにする必要があることを意味します。あなたはDummyImplicit引数で暗黙の引数リストを追加できることを達成するために:

def add(x: Int, y: Int)(implicit dummy: DummyImplicit): Int = x + y 
def add(x: Int)(y: Int): Int = x + y 

このDummyImplicitは、Scalaのライブラリが提供する、およびそれのための暗黙の値は常にあります。今度は、消去後の最初の関数の型が(Int, Int, DummyImplicit)Intで、2番目の関数が(Int, Int)Intなので、JVMはそれらを区別できます。

今、あなたは、両方を呼び出すことができます。

add(1, 2) 
add(1)(2) 
+0

これはかなりクールですが、あまりにもハッキリですが、これまで実用的だと思います。ありがとう! – m0meni

2

したがって、オーバーロードではなく、コンパイルエラーが発生します。私が聞いた

あなたが add(1, 2)add(1)(2)の両方を呼び出すようにしたり、同じことを達成するためにScalaの Default Parameterを使用することができ、以下のKolmarの道( implicitオブジェクト)を使用することができ

def add(a: Int, b: Int, c: Any = DummyImplicit) = a + b // c is default parameter 
def add(a: Int)(b: Int) = a + b 

についてScalaのオーバーロードは良い考えではありません。

あなたは私はあなたが追加使用できる方法(1,2)を持っているWhy "avoid method overloading"?

+0

どのように私は私も提案しています何を達成することができますか?だからadd(1,2)とadd(1)(2)を呼び出すことができます。 – m0meni

+0

私の答えを編集しました。 –

+0

これはあまりにも多くの引数エラーを投げます:/ – m0meni

2

見ると追加することができます(1)(2)しかし、私はそれをお勧めしません。 Scalaの暗黙の定義を使用して、両方のメソッドに対して異なる型を持ちますが、暗黙のメソッドを使用して適切な型に変換します。実行時に、彼らは両方とも(Int, Int)Intです:

case class IntWrapper(value: Int) // Purely to have a different type 

object CurryingThing 
{ 
    def add(x: IntWrapper)(y: IntWrapper) = x.value + y.value 
    def add(x: Int, y: Int) = x + y 

    // The magic happens here. In the event that you have an int, but the function requires an intWrapper (our first function definition), Scala will invoke this implicit method to convert it 
    implicit def toWrapper(x: Int) = IntWrapper(x) 

    def main(args: Array[String]) = { 
    // Now you can use both add(1,2) and add(1)(2) and the appropriate function is called 
    println(add(1,2)) //Compiles, prints 3 
    println(add(1)(2)) // Compiles, prints 3 
    () 
    } 
} 
関連する問題