Haskell 勉強メモ8
高階関数
Haskell は関数を引数にとったり、返り値として関数を返すことができる。このような関数を高階関数と呼ぶ。Scalaにもある。
カリー化関数
Haskellの全ての関数は、引数を1つだけ取る。今まで、複数引数を取っているように見えたものは全てカリー化された関数だ。
Prelude> :t max max :: Ord a => a -> a -> a Prelude> max 4 5 5
max
関数は2つの引数を取り、大きい方を返す関数のように見えるが実際はカリー化された関数。まず、max 4
が適用され、max 4
は1つの値を引数にとる別の関数を返す。返ってきた関数に対して、5が適用されるという流れだ。
Prelude> let max' = max 4 Prelude> :t max' max' :: (Ord a, Num a) => a -> a Prelude>
Scalaもカリー化できる。
def max(a: Int)(b: Int): Int = if (a >= b) a else b max(4)(5) val res0: Int = 5 val max2 = max(4)(_) // val max2: Int => Int = <function>
Scalaの場合はHaskellほど素直ではなく、適用しない部分には _
を入れる必要があるようだ。また、関数部分適用はカリー化されていなくてもできて
def multiThree(x: Int, y: Int, z: Int): Int = x * y * z val m2 = multiThree(3, _, _) // val m2: (Int, Int) => Int = <function> m2(2, 4) // val res2: Int = 24
のように書くこともできる。
今度は、Int
を引数にとって100と比較する関数を作る。これは単純に書くとこうだが
compareWithHundred :: Int -> Ordering compareWithHundred x = compare 100 x *Main> compareWithHundred 99 GT
実際には下記のように書くことができる
compareWithHundred :: Int -> Ordering compareWithHundred = compare 100
compare 100
が引数を一つとって、Ordering
を返す関数であるからだ。