3

暗黙的なメソッドを使用して関数を別のものに変換したい場合、いくつかの問題があります。

テスト目的で Scala 2.8 に小さな DSL を実装しています。インスタンスのさまざまなチェック (必要に応じてアサーション) をサポートする必要があります。DSL 全体は少し複雑ですが、次の単純化された例は私の問題を示しています。

object PimpMyFunction {

  class A(val b: Int)

  def b(a: A) = a.b

  class ZeroCheck(f: A => Int) {
    def isZeroIn(a: A) = f(a) == 0
  }

  implicit def fToCheck(f: A => Int): ZeroCheck = new ZeroCheck(f)     

  def main(args: Array[String]) {
    val a0 = new A(0)
    val a1 = new A(1)

    println(fToCheck(b).isZeroIn(a0))
    println(fToCheck(b).isZeroIn(a1))

    println(b.isZeroIn(a0)) 
  }
}

最初の 2 つの println 行 (変換メソッドを明示的に呼び出した場合) はコンパイルして正常に動作しますが、最後の行 (暗黙に依存したい
Compile error: missing arguments for method b in object PimpMyFunction; follow this method with '_' if you want to treat it as a partially applied function
場合) はエラーを生成します: 「通常の」インスタンス (関数ではない) を暗黙的に変換する場合)同じように機能するため、問題はスコーピング/インポートに関連していないと思います。

エラーメッセージの指示に従って使用すればprintln((b _).isZeroIn(a0))動作しますが、DSL は非技術者を対象としているため、構文はできるだけクリーンでシンプルに保ちたいと考えています。

よりクリーンな構文をサポートする別の回避策 (b は、チェック メソッド + A => Int を既に含むアサーション トレイトを拡張するクラスである必要があります) があると思いますが、より冗長で柔軟性が低いため、暗黙の方法。

構文を回避し(b _)、引き続き暗黙を使用する方法はありますか?

4

2 に答える 2

6

Scala では、(b _) を記述して、メソッド b を関数値にボックス化する必要があることを確認する必要があります。アンダースコアを書きたくない場合は、 b をメソッドではなく関数値として直接定義します。

val b = (a: A) => a.b
于 2010-07-20T10:37:49.993 に答える
4

b関数ではなくメソッドであるため、問題が発生します。そのトピックに関する関連する質問を調べてください。ただし、次のように定義するbと、問題は発生しないはずです。

def b = (_: A).b

これは、 の型がb関数であることを定義します。

于 2010-07-20T12:15:46.650 に答える