2017-12-16 28 views
2

二つの質問適用されます。なぜ私は、彼らが非カリー化されているとき、それは動作しますが、ノート(apply関数はカリー化されたときBaseTraitコンパニオンオブジェクトでこれらの2つのapplyのメソッドを持つことができませんカレーは、形質コンパニオンオブジェクトに

1) 、2つの議論で)?

2)この機能を実現するにはどうすればよいですか?複数の適用方法がカレー化されていますか?

trait BaseTrait[T, U] { 
    def name: String 
    def tryMe(record: T): Option[U] 
} 

object BaseTrait { 
    // can't have both apply methods when curried 
    def apply[T](s: String)(f: T => Option[Long]): LongTrait[T] = 
    new LongTrait[T] { 
     override val name: String = s 
     override def tryMe(record: T): Option[Long] = f(record) 
    } 

    def apply[T](s: String)(f: T => Option[Boolean]): BooleanTrait[T] = 
    new BooleanTrait[T] { 
     override val name: String = s 
     override def tryMe(record: T): Option[Boolean] = f(record) 
    } 
} 

trait LongTrait[T] extends BaseTrait[T, Long] { 
    override def tryMe(record: T): Option[Long] 
} 

trait BooleanTrait[T] extends BaseTrait[T, Boolean] { 
    override def tryMe(record: T): Option[Boolean] 
} 

それは罰金コンパイルしますが、ランタイムエラーがスローされます:あなたは、彼らが最初の引数に異なるように、現在の引数の順序を逆にした場合

scala> BaseTrait("test") { s: String => Option(s.toBoolean) } 

<console>:13: error: ambiguous reference to overloaded definition, 
both method apply in object BaseTrait of type [T](s: String)(f: T => 
Option[Boolean])BooleanTrait[T] 
and method apply in object BaseTrait of type [T](s: String)(f: T => 
Option[Long])LongTrait[T] 
match argument types (String) 
    BaseTrait("test") { s: String => Option(s.toBoolean) } 
+0

私はそれがコンパイルするバグだと思います。それはしないでください。 – Dima

+0

@Dimaあなたは精巧にできますか? Scalaコンパイラは、Function1 [T、Option [Boolean]]とFunction1 [T、Option [Long]]を区別できますが、コンパイルされたJavaコードは区別できませんか?あなたが詳細を持っていれば興味があります。 – user451151

答えて

3

、その適用方法は、呼び出すことができます成功しました。

object BaseTrait { 
    // can't have both apply methods when curried 
    def apply[T](f: T => Option[Long])(s: String): LongTrait[T] = 
     new LongTrait[T] { 
     override val name: String = s 
     override def tryMe(record: T): Option[Long] = f(record) 
     } 

    def apply[T](f: T => Option[Boolean])(s:String): BooleanTrait[T] = 
     new BooleanTrait[T] { 
     override val name: String = s 
     override def tryMe(record: T): Option[Boolean] = f(record) 
     } 
    } 

BaseTrait { s:String => Option(s.toBoolean) }("test") 
res58: BooleanTrait[String] = [email protected] 

this appears to be a corner case in the languageのように、 Wont-Fixステータスで閉じられていた参照された問題では、次の簡単なコードでも同じあいまいな参照の問題が発生します。 Scalaの言語の作成者マーティン・オーダーズキーによる

object Foo { 
    def bar(i: Int) = println(i) 
    def bar(i: Int) (f: Float) = println(i*f) 
} 

は、「私は仕様でそんなことをする試みが存在しないことの上に書きました。私は完全で決定可能ルールのセットを与えるためにあなたに挑戦しますこれをする。"

したがって、必要なチェックを実装するのが難しいため、これらのメソッドを後で参照できなくてもコンパイルできないようです。

+0

問題を指摘してくれてありがとう!これには解決策がない(メソッドの最初の部分を交換する以外に)バマー。 – user451151

関連する問題