1

私は基本的に関数型プログラミングとscalaに不慣れであり、次の質問はおそらくばかげているように見えるかもしれません。

val f = (a:Int) => a+1

上記のスニペットではf、関数または変数と見なす必要がありますか?C / C ++のバックグラウンドから来て、最初に発生するfのは無名関数の戻り値を格納する変数であるということですが、それを解釈する正しい方法ではないと思います。説明は非常に役立ちます。

(私が上で使用した用語のいくつかは、scala /関数型プログラミングに関して間違っている可能性があります、親切にそれに耐えてください)

4

3 に答える 3

5

ここにf、関数を格納する変数があります。次のいずれかを言うのと実際には違いはありません。

val a = 4               // `a` is a variable storing an Int
val b = "hi"            // `b` is a variable storing a String
val f = (a:Int) => a+1  // `f` is a variable storing a function

これはREPLで確認することもできます。

scala> val f = (a:Int) => a+1
f: Int => Int = <function1>

つまり、これはfタイプが。であることを示していますInt => Int。つまり、fは、1つの引数aを取り、。Intを返す関数ですInt

は変数なのでf、メソッドを呼び出すか、その型を期待する関数に引数として渡すことができます。

a + 3  // here I'm calling the `+` method on `a`, which is an Int
f(3)   // here I'm calling the `apply` method on `f`, which is a function `Int => Int`
f(a)   // the function `f` expects an `Int`, which `a` is
(1 to 3).map(f)  // the `map` method expects a function from Int to Int, like `f`
于 2012-09-21T19:27:55.257 に答える
1

はい、dhgが言ったようにf、関数を格納する変数(変更できません)です。

ただし、ここには微妙な点があります。

...最初に考えられるのは、fは無名関数の戻り値を格納する変数であるということです。

f結果ではなく、実際に関数を格納します。したがって、異なる入力を与え、異なる出力を得ることができます。f(7)だから、あなたはそれをのように使うことができますf(5)。Scalaの関数はオブジェクトであるため、変数に割り当てたり、パラメーターとして渡したりすることができます。

私は最近、関数リテラルについて投稿しました。これはあなたに役立つかもしれません。

于 2012-09-21T19:33:05.417 に答える
0

f関数リテラルを示す値です。

ステートメントでは、右側は関数リテラルです。左側はそれをvalueと呼ばれる名前にバインドします(valキーワードはletLISPの場合と同様です)。これで、関数はシンボルに関連付けられたfので、このシンボルを使用してその関数を参照できますf

f私はそれが変数と呼ばれるべきであることを示唆する他の答えに同意しません。は値です。これは、1回だけ決定され、変更できないf右側の項に固定されているためです。逆に、で導入された変数を使用すると、シンボルに値を再割り当てできます。var

var f = (i: Int) => i + 1

var変数定義の始まりは、変数fの名前または記号であり、変数のオプションの定義型が存在する可能性があり(これを省略した場合: ...、型は割り当てから自動的に推測されます)、最初に割り当てられ= ...た値を定義します。変数。

したがって、と言うときは、これを数値定数と混同しないでください。これは、変更されない単なるエンティティです。関数も値にすることができますf。これは、その関数に異なる引数を指定して異なる結果を生成できる場合でも、常に同じ同一の関数を示すためです。

これで、var右側を再割り当てできます。

f(2) // --> 3
f = (i: Int) => i * 2 // assign a new function to the variable f.
f(2) // --> 4

関数型プログラミングとは、変数(再割り当て)を回避することです。


関数を(値または変数に)まったく割り当てずに定義することもできます。以下はそのような関数を定義し、引数を使用してすぐに呼び出します4

{ i: Int => i + 1 } apply 4 // --> 5

それ自体がステートメントとして役立つことはめったにありませんが、関数の引数を期待するメソッドを呼び出すと、「plain」関数が頻繁に表示されます。例えば

val s = List(1, 2, 3)
s.map { (i: Int) => i + 1 } // --> List(2, 3, 4)
s.map { _ + 1 }             // equivalent
s.map( _ + 1 )              // equivalent
于 2012-09-21T23:20:26.683 に答える