Scala Language
高次関数
サーチ…
備考
Scalaはメソッドと関数を構文的に同一のものとして扱うために非常に長きにわたります。しかし、フードの下では、彼らは明確な概念です。
メソッドは実行可能コードであり、値の表現はありません。
関数は、 Function1
型の実際のオブジェクトインスタンス(または別のタイプの同様の型)です。そのコードは、そのapply
メソッドに含まれていapply
。効果的には、単に渡すことができる値として機能します。
ちなみに、値としての機能を治療する能力は、高階関数のサポートを持つ言語が意味する、まさにです 。関数インスタンスは、この機能を実装するためのScalaのアプローチです。
実際の高次関数は、関数値を引数として取るか、関数値を返す関数です。しかし、Scalaでは、すべての操作がメソッドであるため、関数のパラメータを受け取ったり返すメソッドを考えるのが一般的です。したがって、 Seq
定義されているmap
、そのパラメータが関数であるため「高次関数」と考えることができますが、文字通り関数ではありません。方法です。
メソッドを関数値として使用する
Scalaコンパイラは、メソッドを高次関数に渡す目的で自動的にメソッドを関数値に変換します。
object MyObject {
def mapMethod(input: Int): String = {
int.toString
}
}
Seq(1, 2, 3).map(MyObject.mapMethod) // Seq("1", "2", "3")
上記の例では、 MyObject.mapMethod
は関数呼び出しではなく、値としてmap
渡されます。実際には、 map
はそのシグネチャに見られるように、 map
渡される関数値が必要です。 List[A]
(タイプA
のオブジェクトのリスト)のmap
のシグネチャは次のとおりです。
def map[B](f: (A) ⇒ B): List[B]
f: (A) => B
部分は、このメソッド呼び出しのパラメータが、 A
型A
オブジェクトを取り、 B
型のオブジェクトを返す関数であることを示します。 A
とB
は任意に定義される。最初の例に戻って、 mapMethod
はInt
( A
対応)をとり、 String
( B
対応する)を返します。したがって、 mapMethod
はmap
に渡す有効な関数値です。次のように同じコードを書き直すことができます:
Seq(1, 2, 3).map(x:Int => int.toString)
これにより、関数値がインライン化され、単純な関数を明瞭にすることができます。
高次関数(パラメータとしての機能)
一次関数ではなく、高次関数は次の3つの形式のいずれかを持つことができます。
1つ以上のパラメータは関数であり、ある値を返します。
関数を返しますが、そのパラメーターのどれも関数ではありません。
上記の両方:1つ以上のパラメータは関数であり、関数を返します。
object HOF { def main(args: Array[String]) { val list = List(("Srini","E"),("Subash","R"),("Ranjith","RK"),("Vicky","s"),("Sudhar","s")) //HOF val fullNameList= list.map(n => getFullName(n._1, n._2)) } def getFullName(firstName: String, lastName: String): String = firstName + "." + lastName }
ここでmap関数は、 getFullName(n._1,n._2)
関数をパラメータとしてgetFullName(n._1,n._2)
ます。これはHOF(高次関数)と呼ばれます。
引数遅延評価
Scalaは、表記法: def func(arg: => String)
を使用して関数引数の遅延評価をサポートしています。このような関数の引数は、通常のString
オブジェクトまたはString
戻り値の型を持つ高次関数をとることがあります。 2番目のケースでは、関数の引数は値アクセスで評価されます。
例を見てください:
def calculateData: String = {
print("Calculating expensive data! ")
"some expensive data"
}
def dumbMediator(preconditions: Boolean, data: String): Option[String] = {
print("Applying mediator")
preconditions match {
case true => Some(data)
case false => None
}
}
def smartMediator(preconditions: Boolean, data: => String): Option[String] = {
print("Applying mediator")
preconditions match {
case true => Some(data)
case false => None
}
}
smartMediator(preconditions = false, calculateData)
dumbMediator(preconditions = false, calculateData)
smartMediator
呼び出しはNone値を返し、メッセージ"Applying mediator"
ます。
dumbMediator
コールはNone値を返し、 "Calculating expensive data! Applying mediator"
というメッセージを"Calculating expensive data! Applying mediator"
。
レイジー評価は、高価な引数の計算のオーバーヘッドを最適化する場合に非常に役立ちます。