- 関数を引数として受け取るメソッドと関数、あるいは関数を返す関数の両方に対して高階関数という
- 下記はScalaのコレクションでよく利用される高階関数
mapの例
val salaries = Seq(20_000, 70_000, 40_000)
val doubleSalary = (x: Int) => x * 2
val newSalaries = salaries.map(doubleSalary) // List(40000, 140000, 80000)- コードを短縮するために、関数を匿名化して直接
mapに引数として渡すこともできる- コンパイラが
xの型を推論しているので、Int型の宣言は不要
- コンパイラが
val salaries = Seq(20_000, 70_000, 40_000)
val newSalaries = salaries.map(x => x * 2) // List(40000, 140000, 80000)xの代わりに_を使用することで、コードを更に簡略化できる
val salaries = Seq(20_000, 70_000, 40_000)
val newSalaries = salaries.map(_ * 2) // List(40000, 140000, 80000)メソッドを関数に強制変換する
- Scalaのコンパイラはメソッドを高階関数に渡すと、関数に強制変換させる
case class WeeklyWeatherForecast(temperatures: Seq[Double]):
private def convertCtoF(temp: Double) = temp * 1.8 + 32
def forecastInFahrenheit: Seq[Double] = temperatures.map(convertCtoF)関数を受け入れる関数
- 高階関数を使用する理由の一つに、冗長なコードを削減することにある
object SalaryRaiser:
// map呼び出しが冗長
def smallPromotion(salaries: List[Double]): List[Double] =
salaries.map(salary => salary * 1.1)
def greatPromotion(salaries: List[Double]): List[Double] =
salaries.map(salary => salary * math.log(salary))
def hugePromotion(salaries: List[Double]): List[Double] =
salaries.map(salary => salary * salary)
object SalaryRaiser:
// promotionとして高階関数に抽出してDRYを実現させる
private def promotion(salaries: List[Double], promotionFunction: Double => Double): List[Double] =
salaries.map(promotionFunction)
def smallPromotion(salaries: List[Double]): List[Double] =
promotion(salaries, salary => salary * 1.1)
def greatPromotion(salaries: List[Double]): List[Double] =
promotion(salaries, salary => salary * math.log(salary))
def hugePromotion(salaries: List[Double]): List[Double] =
promotion(salaries, salary => salary * salary)関数を返す関数
- 関数を返す関数を定義することもできる
def urlBuilder(ssl: Boolean, domainName: String): (String, String) => String =
val schema = if ssl then "https://" else "http://"
(endpoint: String, query: String) => s"$schema$domainName/$endpoint?$query"
val domainName = "www.example.com"
def getURL = urlBuilder(ssl=true, domainName)
val endpoint = "users"
val query = "id=1"
val url = getURL(endpoint, query)
println(url) // https://www.example.com/users?id=1次章:[[]]