Posted at

すごいH本読んだからまとめ 6 「カリー化」


はじめに


カリー化



  • 複数の引数を取る関数が、引数の一部を受けとったとき、残りの引数を受け付けて元の関数の値を返す関数である場合、それはカリー化された関数である。

  • Haskellの関数はすべてカリー化されている。


-- 複数の引数を取る関数
*Main Lib> sum' a b = a + b
-- 定義した関数に引数の一部を渡し(部分適用)、「残りの引数を受け付けて値を返す」関数を保存する。
*Main Lib> sum3 = sum' 3
-- 定義した関数に残りの引数を与えてみる(関数適用)
*Main Lib> sum3 5
8

部分適用は左側から行われる


-- 3つの引数を受け取って値を帰す関数
function :: a -> b -> c -> d -- a -> (b -> (c -> d))
-- aだけ部分適用
functionA = function a -- b -> c -> d
-- aとbを部分適用
functionAB = function a b -- c -> d
-- aとbとcを適用(普通の関数実施)
functionABC = function a b c -- d

中置き関数は、書き方によって適用順が変わる。

-- 10 「を」割る

*Main Lib> tenDivide = (10 /)
*Main Lib> tenDivide 5
2.0
*Main Lib> tenDivide 2
5.0

-- 10「で」割る
*Main Lib> divide10 = (/10)
*Main Lib> divide10 100
10.0
*Main Lib> divide10 1
0.1

-- マイナス(-)は負の値を表す演算子として定義される。
*Main Lib> minus10 = (-10)
*Main Lib> minus10 12

<interactive>:14:1: error:
? Non type-variable argument in the constraint: Num (t1 -> t2)
(Use FlexibleContexts to permit this)
? When checking the inferred type
it :: forall t1 t2. (Num t1, Num (t1 -> t2)) => t2

-- こういう書き方もできる。

isUpperAlphanum :: Char -> Bool
isUpperAlphanum = (`elem` ['A'..'Z'])
*Main> isUpperAlphanum 'S'
True
*Main> isUpperAlphanum 's'
False