Haskell Curryingについて少し

M. Lipovac「Study Haskell for Good!」を読んで、最初は部分的な適用カリー とどのように異なるのか理解できませんでした。 この問題の分析に時間を費やし、トピックに関する「チートシート」をスケッチしました。



Haskellでは、パラメータのない関数は、 定義または名前と呼ばれます

func :: String func = "Haskell"
      
      





関数は複数のパラメーターを取ることができません。 関数が複数のパラメーターをとる場合、 実際には1つのパラメーターを持つ関数であり、 1つのパラメーターのみを取り、何らかの結果( 別の関数または特定の値 )を返す別の関数を返します。 関数に次のシグネチャがある場合:

 func :: Int -> Double -> Char -> Bool
      
      





Haskellは次のように解釈します:

 func :: Int -> (Double -> (Char -> Bool))
      
      





つまり func関数は、Int型の引数を取り、Double型の次の引数を受け取る新しい関数を返し、Char型の引数を取り、Bool型の値を返す別の新しい関数を返します。

関数を多数の引数から一度に1つの引数を取る関数に変換することをカリー化と呼びます。 Haskellは、複数のパラメーターを取るすべての関数を自動的にカリー化します。 カリー化のおかげで、 セクションを作成するだけでなく、関数を部分的に使用することが可能になりました。 同様に、部分適用により、 無意味な表記の存在が可能になります。

ご注意



Haskellで関数を部分的に使用するようなことはありません。 機能アプリケーションがあります (「部分的に」なし)。 関数f :: Int -> Int -> Int



に2つの引数 (技術的には正しくない)があると(知覚の便宜のために) 言う場合、同じ(知覚の便宜のために)同じことを言うことができます。 f 5



部分的に適用された関数です(技術的には正しくありません)。




 func :: (Num a) => a -> a -> a -> a func abcd = a + b + c + d
      
      





ghci



部分適用:

 λ: let n = func 2 3 λ: let m = n 10 λ: let g = m 7 λ: g 22
      
      





セクション:

 λ: let a = (/2) λ: a 10 5.0 λ: let b = (15/) λ: b 5 3.0
      
      





無意味な表記法:

 odd' :: Integral a => a -> Bool odd' = odd
      
      





ghci:

 λ: odd' 5 True λ: odd' 4 False
      
      







カリー化と宣言



次の関数は、標準のData.Tupleモジュールで定義されています。

 curry :: ((a, b) -> c) -> a -> b -> c uncurry :: (a -> b -> c) -> (a, b) -> c
      
      





カレー関数は、非カリー関数をカリー関数に変換します。

uncurry関数は、カリー化された関数をカリー化されていない関数に変換します。



 msg :: Int -> Bool -> String msg n True = show $ n `div` 2 msg n _ = show $ n * 2
      
      





ghci



 λ: let n = msg λ: let m = uncurry n λ: :tn n :: Int -> Bool -> String λ: :tm m :: (Int, Bool) -> String λ: n 5 True "2" λ: m (5,True) "2" λ: let k = curry m λ: :tk k :: Int -> Bool -> String λ: k 5 True "2"
      
      






All Articles