2012-06-10 6 views
10

私はカレー機能に関するいくつかの質問があります。ここで私はそれらを1つずつ尋ねますスカラのカリング関数関連の質問

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 
         ^
+0

1)これは無効です。最初に宣言する必要があるためです。たとえば、次のようにします。 'def multiplyThenFilter(a:Int => Int)(b:Int => Boolean)= {List(1,2,3,4).map(a)。filter(b)} ' –

+0

1)multiplyThenFilterは今やなくなっています。あなたはそれによって混乱した唯一の人物ではありません:-) –

答えて

11

質問1

Scalaの学校の例混乱 - それは間違いな定義はありませんです。 an issueがGitHubに公開されているので、バグかもしれません。あなたは合理的な定義は次のようになります想像することができます:(。または、同等に、f andThen (Some(_) filter p)

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

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


質問2

あなたtimesTwoが動作しないという理由はScalaのコンパイラは型推論-参照関連の細部のビットのためのthis questionmy answer thereのようなものをサポートしていないだけということです。あなたは、次のいずれかに移動する必要があります:

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) 

これはちょうどdoesnのFunction1、である」をcurriedメソッドがあります。そのためにはFunction2(またはFunction3など)が必要です。

ただ1つの引数で関数をカリングすることについて話すのは意味がありません。 Curryingは、複数の引数を持つ関数を取り、別の関数を返す単一の引数を取る関数を提供します(それ自体は単一の引数をとり、別の関数などを返します)。

+0

は、答えに "val timesTwo = multiply(2、_:Int)"と "val timesTwo = multiply(2)_"で定義された2つの関数 'timesTwo'同じタイプの質問2に? – chen

+0

はい、それらは両方とも 'Int => Int'(または同等には' Function1 [Int、Int] ')です。 –