2015-09-23 28 views
11

私はカレーに関する多くの記事を読んできましたが、ほとんどすべてが誤解を招き、部分的な関数アプリケーションとしてのカリー化を説明しています。例はすべてadd関数などの2のアリティを持つ関数です。カレーの実際の使用例は何ですか?

その機能の評価を翻訳

Wikipedia articleは明らかにカリー化を約あることを伝えたときにJavaScriptでcurry機能の

また、多くの実装では、(lodashを参照)、それは部分的にアプリケーションごとに1つの以上の引数を受け入れるようになります(部分アプリケーション)

基本的にカリングは、それぞれが単一の引数を持つ一連の部分アプリケーションです財産そして、私は本当にそれをあらゆる言語で実際に使用したいと思っています。

+0

これらの用語の他の用途は「間違っている」と思いますか? – dfeuer

答えて

7

実際のカリングの使用例は部分的な応用です。

それ自体でカレーすることはあまり面白いことではありません。興味深いのは、プログラミング言語がF#またはHaskellの場合のように、デフォルトでカリングをサポートしている場合です。

ファーストクラスの関数をサポートする任意の言語でカリングや部分的なアプリケーションに高次関数を定義することはできますが、得られる関数がカレット化されたときの柔軟性とはまったく異なります。何でもする。

カリングが部分的に絡み合っているのを見れば、それはそのコンセプトがどれほど密接に結びついているからです。カリー化は遍在しているので、カリー化された関数を連続する引数に適用する以外には、

+3

OPの立場にあり、最近カレーの魅力を見に来た人として、私はこの答えにもっと同意できませんでした。 https://drboolean.gitbooks.io/mostly-adequate-guide/content/ch4.htmlとhttp://ramdajs.com/0.17/docs/#curryを読んだら、事柄は意味をなさない!すべての機能をデフォルトでカリングしておくことは、部分的に適用された関数をコード内の「ビルディングブロック」として使用することを可能にします。 – TW80000

4

コンテキストを渡すと便利です。

「地図」機能について考えてみましょう。これは、引数として関数を取ります。これは、あなたがエレガントな「A'-引数を述べることなく、マップ機能を使用できることを意味します

f : SomeContext -> a -> b 

:コンテキストのいくつかのフォームを使用して機能を考えると

map : (a -> b) -> [a] -> [b] 

map (f actualContext) [1,2,3] 

カリー化がなければ、あなたは、ラムダを使用する必要があります210の

map

a、関数fの値を含むリストを取る関数です。新しいリストを作成するには、それぞれaを取得してfを適用すると、b

のリストが作成されます。 map (+1) [1,2,3] = [2,3,4]

1

軸受カリー化は、問題(私は説明するためのHaskellを使用)の2つのセットに分割することができるコードを有しています。 構文、実装。

構文問題1:

カリー化は、特定の場合においてより大きなコード明瞭さを可能にします。 明快さは何を意味しますか?この機能を読み取ることで、その機能性が明確に示されます。例: マップ関数。このように

map : (a -> b) -> ([a] -> [b]) 

読むには、我々は、マップが[b][a]を変換関数にbsからasを変換する機能を持ち上げる高階関数であることがわかります。

このような直感は、そのような式を理解するときに特に便利です。

map (map (+1)) 

内側マップのタイプは、[a] -> [b]です。 外部地図の種類を理解するために、我々は上から直観を再帰的に適用する。外側の地図は[a] -> [b][[a]] -> [[b]]に持ち上げます。

この直感はあなたに多くを転送します。 mapfmapmapに任意のコンテナで一般化すれば、本当に簡単に式を読むことができます(この例では、fmapの型を別の型に単調変更しています)。

showInt : Int -> String 
(fmap . fmap . fmap) showInt : Tree (Set [Int]) -> Tree (Set [String]) 

は、うまくいけば、上記fmapがある任意の容器上関数にバニラ機能を持ち上げるこの一般概念を提供することを示します。

構文の問題2:

カリー化もポイントのない形で機能を表現することを可能にします。

nthSmallest : Int -> [Int] -> Maybe Int 
nthSmallest n = safeHead . drop n . sort 

safeHead (x:_) = Just x 
safeHead _  = Nothing 

上記は通常、データの明示的な操作ではなく機能のパイプラインという考え方を示すため、良いスタイルと考えられています。

実装:Haskellで

、(カリー化を介して)ポイント自由なスタイルは、私たちは機能を最適化することができます。ポイントフリーの形式で関数を書くことで、私たちはそれをメモすることができます。メモ化バージョンのようカリー関数として書く

memoized_fib :: Int -> Integer 
memoized_fib = (map fib [0 ..] !!) 
    where fib 0 = 0 
      fib 1 = 1 
      fib n = memoized_fib (n-2) + memoized_fib (n-1) 


not_memoized_fib :: Int -> Integer 
not_memoized_fib x = map fib [0 ..] !! x 
    where fib 0 = 0 
      fib 1 = 1 
      fib n = not_memoized_fib (n-2) + not_memoized_fib (n-1) 

エンティティとしてカリー機能を扱い、したがって、それをmemoizes。

関連する問題