11

カレー関数に関連するいくつかの質問があります。ここで一人ずつ聞く

1) http://twitter.github.com/scala_school/basics.htmlは、カリー化された関数の例を示しています。これは関数定義だと思っていましたが、実際にはそうではありません。REPL は、これを有効なステートメントとしてまったく認識しません。

multiplyThenFilter { m: Int =>   m * 2 } { n: Int =>   n < 5}

2) 部分的にパラメータ化されたメソッドから関数を定義できないのはなぜですか? つまり、次の定義のどこが間違っているのでしょうか?

scala> def multiply(m: Int, n: Int): Int = m * n
multiply: (m: Int, n: Int)Int

scala> val timesTwo = multiply(2,_)
<console>:11: error: missing parameter type for expanded function ((x$1) => multiply(2, x$1))
       val timesTwo = multiply(2,_)
                                 ^

3) 部分的にパラメータ化された関数をカリー化できないのはなぜですか? つまり、次の定義のどこが間違っているのでしょうか?

scala> (multiply(_,_)).curried
  res13: Int => (Int => Int) = <function1>  // THIS IS OK

scala> (multiply(20,_)).curried
<console>:12: error: missing parameter type for expanded function ((x$1) => multiply(20, x$1))
              (multiply(20,_)).curried
                           ^
4

1 に答える 1

12

質問1

Scala School の例紛らわしいです — これは間違いなく定義ではありません。GitHub で問題が公開されているため、バグである可能性があります。合理的な定義は次のようになると想像できます。

def multiplyThenFilter(f: Int => Int)(p: Int => Boolean): Int => Option[Int] = {
  i =>
    val j = f(i)
    if (p(j)) Some(j) else None
}

(または、同等に、f andThen (Some(_) filter p).)

この例は、入力を 2 倍にし、Some5 未満の場合は結果を返し、それ以外の場合は結果を返す関数になりNoneます。しかし、その問題への反応があるまで、著者が意図したことを正確に知る人は誰もいません.


質問2

your が機能しない理由timesTwoは、Scala コンパイラがその種の型推論をサポートしていないためです。関連する詳細については、この質問そこにある私の回答を参照してください。次のいずれかを使用する必要があります。

def multiply(m: Int, n: Int): Int = m * n    
val timesTwo = multiply(2, _: Int)

def multiply(m: Int)(n: Int): Int = m * n    
val timesTwo = multiply(2) _

つまり、ここで型の推論が必要な場合は、複数のパラメーター リストを使用する必要があります。それ以外の場合は、型でコンパイラを支援する必要があります。


質問 3

3 番目の質問については、2 番目の質問の問題を回避するために、次のことを前提としています。

val timesTwo = multiply(2, _: Int)

これはメソッドをFunction1持たないです。そのためには(またはなど) が必要です。curriedFunction2Function3

単一の引数で関数をカリー化することについて話すのは意味がありません。カリー化は、複数の引数を持つ関数を取り、別の関数を返す単一の引数を取る関数を提供します (それ自体が単一の引数を取り、別の関数を返す可能性があります)。

于 2012-06-10T19:23:34.620 に答える