25

これがすでに他の場所で尋ねられているなら、私を許してください。関数値と暗黙のパラメーターに関するScala構文の質問があります。

私はScalaのカリー化機能で暗黙を使用することに慣れています。たとえば、sum関数があり、2番目の引数を暗黙的にしたい場合:

scala> def sum(a: Int)(implicit b: Int) = a + b
sum: (a: Int)(implicit b: Int)Int

関数値構文を使用してこれを行う方法はありますか?暗黙の値を少し無視して、私は通常、次のようなカリー化された関数値を記述します。

scala> val sum2 = (a: Int) => (b: Int) => a + b
sum: (Int) => (Int) => Int = <function1>

ただし、2番目のアプローチの関数シグネチャは大きく異なります(カリー化は明示的に表現されています)。暗黙のキーワードをbに追加するだけではあまり意味がなく、コンパイラも文句を言います。

scala> val sum2 = (a: Int) => (implicit b: Int) => a + b
<console>:1: error: '=>' expected but ')' found.
       val sum2 = (a: Int) => (implicit b: Int) => a + b
                                              ^

さらに、関数値を取得するための最初のアプローチからの合計を部分的に適用すると、同様に問題が発生します。

scala> val sumFunction = sum _
<console>:14: error: could not find implicit value for parameter b: Int
       val sumFunction = sum _
                         ^

これにより、暗黙のパラメーターを持つ関数は、関数値が後で適用されるときではなく、関数値が作成されるときに決定されたパラメーターを持っている必要があると私は信じています。これは本当に本当ですか?関数値で暗黙のパラメーターを使用できますか?

助けてくれてありがとう!

4

3 に答える 3

19
scala>  val sum2 = (a: Int) => {implicit b: Int => a + b}
sum2: (Int) => (Int) => Int = <function1>

これにより、bが関数本体のスコープの暗黙の値になるため、暗黙のIntを期待するメソッドを呼び出すことができます。

関数が何であるかは不明なので、関数に対して暗黙の引数を持つことはできないと思います。それInt => Intですか() => Int

私が見つけた最も近いものは次のとおりです。

scala> case class Foo(implicit b: Int) extends (Int => Int) {def apply(a: Int) = a + b}
defined class Foo

scala> implicit val b = 3
b: Int = 3

scala> Foo()
res22: Foo = <function1>

scala> res22(2)
res23: Int = 5
于 2011-06-13T03:11:05.657 に答える
9

このスニペットでは

scala> val sum2 = (a: Int) => (b: Int) => a + b
sum: (Int) => (Int) => Int = <function1>

の正確なタイプはsum2ですFunction1[Int, Function1[Int, Int]]。また、次のように書くこともできます

val sum2 = new Function1[Int, Function1[Int, Int]] {
    def apply(a: Int) = new Function1[Int, Int] {
        def apply(b: Int) = a + b
    }
}

さて、暗黙的にしようとするとb、次のようになります。

scala>     val sum2 = new Function1[Int, Function1[Int, Int]] {
     |         def apply(a: Int) = new Function1[Int, Int] {
     |             def apply(implicit b: Int) = a + b
     |         }
     |     }
<console>:8: error: object creation impossible, since method apply in trait Function1 of type (v1: Int)Int is not defined
               def apply(a: Int) = new Function1[Int, Int] {
                                       ^

または、言い換えると、Functionのインターフェイスには暗黙のパラメータがないため、暗黙のパラメータを持つものはすべてではありませんFunction

于 2011-06-13T03:47:54.080 に答える
5

applyメソッドをオーバーロードしてみてください。

scala> val sum = new Function1[Int, Function1[Int, Int]] {
         |      def apply(a: Int) = (b: Int) => a + b
         |      def apply(a: Int)(implicit b: Int) = a + b
         |}
sum: java.lang.Object with (Int) => (Int) => Int{def apply(a:Int)(implicit b: Int): Int} = <function1>

scala> sum(2)(3)
res0: Int = 5

scala> implicit val b = 10
b: Int = 10

scala> sum(2)
res1: Int = 12
于 2011-06-14T15:12:58.750 に答える