2011-09-02 2 views
9

私はこの複数のパラメータ句の言語機能のポイントと、なぜそれを使うのかを理解しようとしています。 たとえば、これらの2つの機能の違いは何ですか?Scalaの関数定義における複数のパラメータ節のポイントは何ですか?

class WTF { 
    def TwoParamClauses(x : Int)(y: Int) = x + y 
    def OneParamClause(x: Int, y : Int) = x + y 
} 

>> val underTest = new WTF 
>> underTest.TwoParamClauses(1)(1) // result is '2' 
>> underTest.OneParamClause(1,1) // result is '2' 

Scala specification at point 4.6には何かがあります。それがあなたにとって意味をなさないかどうかを見てください。

NB:仕様ではこれらの「パラメータ句」が呼び出されていますが、一部の人は「パラメータリスト」と呼んでいると思います。

+0

Nnon、Scalaのプログラマーここで、前回のパラメータに基づいて、デフォルト値を設定するには2つのパラメータリスト、

// analogous to a context bound: g3[A : Ordering](x: A) def g3[A](x: A)(implicit ev: Ordering[A]) {} 
  • が必要です。多分それはちょうど別のスタイルですか?すべてがそれを行う一つの方法しか持たないというわけではありません。 – apscience

  • +0

    大丈夫、ダニエル・ソブラルの答えは、http://stackoverflow.com/questions/4697404/scala-currying-by-nested-functions-or-by-multiple-parameter-lists –

    +0

    にお答えしています答えはおそらくこの質問に答えるでしょう:(1)2番目の節の最初のparam句の型を指定する必要はありません。 (2)ライブラリ設計の柔軟性。 (3)カリングを簡単にする:http://stackoverflow.com/questions/4915027/two-ways-of-currying-in-scala-whats-the-use-case-for-each –

    答えて

    9

    は、型推論を支援するために、複数のパラメータリストの3つの実用的な用途、

    1. です。これは、高次のメソッドを使用する場合に特に便利です。以下、g2の型パラメータAは、最初のパラメータxから推測されるので、第二パラメータfにおける関数の引数は、暗黙のパラメータについて

      def g1[A](x: A, f: A => A) = f(x) 
      g1(2, x => x) // error: missing parameter type for argument x 
      
      def g2[A](x: A)(f: A => A) = f(x) 
      g2(2) {x => x} // type is inferred; also, a nice syntax 
      
    2. を省略させることができます。最後のパラメータリストのみが暗黙的にマークされ、単一のパラメータリストは暗黙のパラメータと暗黙的でないパラメータを混在させることができません。 g3の定義は、以下の

      def g4(x: Int, y: Int = 2*x) {} // error: not found value x 
      def g5(x: Int)(y: Int = 2*x) {} // OK 
      
    3

    この区別は重要ないくつかのケースがあります。

    1. 複数のパラメータリストは、あなたがTwoParamClauses(2)のようなものを持ってすることができます。 Int => Int型の自動的に生成された関数で、引数に2を加えます。もちろん、あなた自身が、同様OneParamClause使用して同じことを定義することができますが、それはあなたにも、明示的なパラメータがあり、暗黙のパラメータを持つ関数を持っている場合は、暗黙のパラメータは(すべて、独自のパラメータ句である必要がありますより多くのキーストローク

    2. がかかりますこれは、それ以外

    )任意の制約と思われるが、実際には非常に賢明であることが、私が思うに、違いが文体です。

    8

    TwoParamClauseは、OneParamClause ファンクション メソッドを1回呼び出すのに対し、2回のメソッド呼び出しを含みます。あなたが探している用語はキールです。多くのユースケースの中で、計算を小さなステップに分解するのに役立ちます。このanswerは、カレー加工の有用性をあなたに納得させるかもしれません。

    +1

    2つのパラメータ句を持つフォームは、*メソッド*を1回だけ呼び出します。その呼び出しの結果は*関数*であり、最後に適用されます。 –

    +1

    @pst:しかし、関数を適用すると、メソッドも呼び出されます(つまり、関数の 'apply'メソッド)。 –

    +0

    @Alexey Romanov真実。元の投稿文言は異なっていました;-)私は、今の日付のコメントでは、メソッド(オブジェクトが "どのように"応答するかを知っているもの)と関数(適用可能な個別オブジェクトそのようなアプリケーションがその上でメソッドを呼び出す結果である場合)。私はまだ用語に同意しない "...1回だけ 'OneParamClause'メソッド*を呼び出すため、この関数を1回だけ呼び出します。 –

    4

    複数のパラメータリストは、詳細については、Scalaの型推論を助けることができます参照してください:情報のみから、内左から右に引数リスト流れないMaking the most of Scala's (extremely limited) type inference

    タイプは、左から右へ引数リストを渡ります。だから、Scalaは最初の2つの引数の型を知っています...その情報は私たちの無名関数には流れません。したがって、今、私たちのバイナリ関数は別々の引数リストにあることを、以前引数リストからあらゆるタイプの情報は、当社の機能の型を埋めるために使用されている

    ...

    ...私たちは、ラムダのパラメータに注釈を付ける必要はありません。

    +0

    投稿にベアリンクだけでなく、抜粋や推論を含めてください。しかし、 –

    +0

    私は私の短い記述が悩まされ、完全な参考のためにブログを読むべきであると思った。 – AndreasScheinert

    6

    タイプ推論には2つのバージョンの違いがあります。ここで

    def f[A](a:A, aa:A) = null 
    f("x",1) 
    //Null = null 
    

    を考えてみましょう、タイプAStringIntのスーパータイプがある、Anyにバインドされています。しかし:あなたが見たよう

    def g[A](a:A)(aa:A) = null 
    g("x")(1) 
    
    error: type mismatch; 
    found : Int(1) 
    required: java.lang.String 
         g("x")(1) 
          ^
    

    は、型チェッカーはだけなのでAStringにバインドされます、最初の引数リストを考慮し、その第二引数リストのaaためInt値は、型エラーです。ここで

    関連する問題