5

だから何かのような

addList :: [int] -> int
addList = foldl1 (+)

なぜこれが機能するのですか?カリー化部分。なぜ変数がないのですか?

4

3 に答える 3

11

のような関数を定義する場合f x y = bla、これはと同じf x = \y -> blaであり、はと同じf = \x -> (\y -> bla)です。つまりf、1つの引数を取り、1つの引数を取り、実際の結果xを返す別の関数を返す関数です。yこれはカリー化として知られています。

同様に、あなたがするときf x y、それはと同じ(f x) yです。fつまり、引数を指定して関数を呼び出していますx。これにより、引数に適用する別の関数が返されますy

つまり、を実行するとaddList xs = foldl1 (+) xs、最初に呼び出しfoldl1 (+)て、次に適用する別の関数を返しますxs。したがって、によって返される関数foldl1 (+)は実際にはと同じであるaddListため、に短縮することができますaddList = foldl1 (+)

于 2010-09-25T15:35:51.873 に答える
5

カリー化に加えて、sepp2kが指摘したように、ここではいわゆるイータリダクションを使用します。これは、Haskellの基礎となるラムダ計算の削減ルールの1つです。に表示されない場合\x -> f xと同等です。fxf

あなたのケースにそれを適用しましょう。私はあなたがのような定義に満足していると思いますaddList xs = foldl1 (+) xs。これを次のように書き直して、addList = \xs -> foldl1 (+) xs取得したeta削減ルールを適用できaddList = foldl1 (+)ます。

このルールは、同じ引数に適用したときに2つの関数が等しい結果をもたらす場合、2つの関数は等しいという考えに基づいています。ここでの2つの関数はfg = \x -> f xどこにあり、すべての、f : a -> bに対してそれを示したいと思います。それが任意であることを証明し、それを:に適用するために、最後の等式は、関数適用が置換によって評価されることを示すベータ削減と呼ばれる別の規則によるものです。c : af c = g cc : agg c = (\x -> f x) c = f c

于 2010-09-25T18:01:59.640 に答える
2

sepp2kからの説明は正しいですが、このカリー化のアプリケーションには「ポイントフリースタイル」と呼ばれる名前があることを指摘したいと思います(しゃれを意図しています)。ここに賛否両論を含む良い説明があります:http://www.haskell.org/haskellwiki/Pointfree

于 2010-09-25T17:56:32.400 に答える