[解決済み] ScalaでCurryする2つの方法、それぞれのユースケースは?
質問
私は、以下のような議論をしています。 複数のパラメータ・リスト という記述があります。の2つの方法があることに気がつきました. カーリング という2つの方法があることに気づきましたが、どのようなユースケースがあるのでしょうか。
def add(a:Int)(b:Int) = {a + b}
// Works
add(5)(6)
// Doesn't compile
val f = add(5)
// Works
val f = add(5)_
f(10) // yields 15
def add2(a:Int) = { b:Int => a + b }
// Works
add2(5)(6)
// Also works
val f = add2(5)
f(10) // Yields 15
// Doesn't compile
val f = add2(5)_
スタイル ガイドでは、明らかに異なるのに、これらが同じであるかのように誤って解釈しています。このガイドでは、作成された curried 関数について指摘しようとしており、2 番目の形式は "by-the-book" currying ではないものの、最初の形式と非常に似ています (しかし、間違いなく
_
)
これらのフォームを使用している人たちから、どのような場合に一方のフォームを他方よりも使用するかについて、コンセンサスは得られていますか?
どのように解決するのですか?
複数のパラメータを持つリストメソッド
型推論用
複数のパラメータセクションを持つメソッドは、最初のセクションのパラメータを使用して、後続のセクションの引数に期待される型を提供する型引数を推論することにより、局所的な型推論を支援するために使用することができます。
foldLeft
はこの典型的な例です。
def foldLeft[B](z: B)(op: (B, A) => B): B
List("").foldLeft(0)(_ + _.length)
と書かれたこれだったら。
def foldLeft[B](z: B, op: (B, A) => B): B
より明示的な型を提供しなければならないだろう。
List("").foldLeft(0, (b: Int, a: String) => a + b.length)
List("").foldLeft[Int](0, _ + _.length)
流れるようなAPIのために
複数のパラメータを持つセクションメソッドのもう一つの使い方は、言語の構成要素のように見えるAPIを作ることです。呼び出し側は括弧の代わりに中括弧を使用することができます。
def loop[A](n: Int)(body: => A): Unit = (0 until n) foreach (n => body)
loop(2) {
println("hello!")
}
N個の引数リストをM個の引数セクションを持つメソッドに適用する場合、N < Mは、関数に明示的に変換するために
_
で明示的に、あるいは暗黙的に、期待される型として
FunctionN[..]
. これは安全な機能です。背景については Scala リファレンスの Scala 2.0 の変更ノートを参照してください。
Curried Functions
曲線関数(または単に関数を返す関数)は、N個の引数リストに対してより簡単に適用することができます。
val f = (a: Int) => (b: Int) => (c: Int) => a + b + c
val g = f(1)(2)
このちょっとした便利さは、時には価値があります。しかし、関数は型パラメトリックであることができないので、場合によってはメソッドが必要であることに注意してください。
2つ目の例はハイブリッドです。関数を返す1つのパラメータセクションメソッドです。
多段階計算
curried関数は他にどこで役に立つのでしょうか?よく出てくるパターンを紹介しましょう。
def v(t: Double, k: Double): Double = {
// expensive computation based only on t
val ft = f(t)
g(ft, k)
}
v(1, 1); v(1, 2);
結果をどのように共有するか
f(t)
? 一般的な解決策は、ベクター化された
v
:
def v(t: Double, ks: Seq[Double]: Seq[Double] = {
val ft = f(t)
ks map {k => g(ft, k)}
}
醜い! 関係ないものを絡めてしまった -- 計算中
g(f(t), k)
の計算と、一連の
ks
.
val v = { (t: Double) =>
val ft = f(t)
(k: Double) => g(ft, k)
}
val t = 1
val ks = Seq(1, 2)
val vs = ks map (v(t))
また、関数を返すメソッドを使うこともできます。この場合、もう少し読みやすくなります。
def v(t:Double): Double => Double = {
val ft = f(t)
(k: Double) => g(ft, k)
}
しかし、複数のパラメータセクションを持つメソッドで同じことをしようとすると、行き詰ってしまいます。
def v(t: Double)(k: Double): Double = {
^
`-- Can't insert computation here!
}
関連
-
[解決済み] Scalaでは、'val a. = _' (アンダースコア)は具体的にどのような意味ですか?A = _' (アンダースコア)とはどういう意味ですか?
-
[解決済み] SBTが終了せずに実行を停止する
-
[解決済み] Scalaでリストを2つのフィールドでソートするには?
-
[解決済み] Scalaの自動リソース管理にはどのようなものがありますか?
-
[解決済み] コレクションのGroovyマップメソッド
-
[解決済み] Scalaで使える数学・統計のライブラリはありますか?[クローズド]
-
[解決済み] Scalaの::と::の違いは何ですか?
-
[解決済み] マルチプロジェクトにおけるSBTのテスト依存性。依存するプロジェクトでテストコードを利用できるようにする
-
[解決済み] Scalaのメソッド宣言で等号を使用するのはいつですか?
-
[解決済み] HashPartitionerはどのように機能するのですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] Scalaでmapを使用してインデックスを受け取るにはどうしたらいいですか?
-
[解決済み] Scalaでリストを2つのフィールドでソートするには?
-
[解決済み] Scalaでimmutable.Mapをmutable.Mapに変換するにはどうしたらいいですか?
-
[解決済み] Scalaで、リストから重複を取り除くにはどうしたらいいですか?
-
[解決済み] Scalaのtraitでvalとdefの使い分けは?
-
[解決済み] Scala における => と () => の意味 [重複].
-
[解決済み] flatMap/Map変換のfor-comprehensionで迷う。
-
[解決済み] Scalaの複数型パターンマッチ
-
[解決済み] Scalaの継続性とは何か、なぜ継続性を使うのか?
-
[解決済み] Scalaの複数パラメータリストと複数パラメータ/リストの違いは何ですか?