だから何かのような
addList :: [int] -> int
addList = foldl1 (+)
なぜこれが機能するのですか?カリー化部分。なぜ変数がないのですか?
だから何かのような
addList :: [int] -> int
addList = foldl1 (+)
なぜこれが機能するのですか?カリー化部分。なぜ変数がないのですか?
のような関数を定義する場合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 (+)
。
カリー化に加えて、sepp2kが指摘したように、ここではいわゆるイータリダクションを使用します。これは、Haskellの基礎となるラムダ計算の削減ルールの1つです。に表示されない場合\x -> f x
と同等です。f
x
f
あなたのケースにそれを適用しましょう。私はあなたがのような定義に満足していると思いますaddList xs = foldl1 (+) xs
。これを次のように書き直して、addList = \xs -> foldl1 (+) xs
取得したeta削減ルールを適用できaddList = foldl1 (+)
ます。
このルールは、同じ引数に適用したときに2つの関数が等しい結果をもたらす場合、2つの関数は等しいという考えに基づいています。ここでの2つの関数はf
とg = \x -> f x
どこにあり、すべての、f : a -> b
に対してそれを示したいと思います。それが任意であることを証明し、それを:に適用するために、最後の等式は、関数適用が置換によって評価されることを示すベータ削減と呼ばれる別の規則によるものです。c : a
f c = g c
c : a
g
g c = (\x -> f x) c = f c
sepp2kからの説明は正しいですが、このカリー化のアプリケーションには「ポイントフリースタイル」と呼ばれる名前があることを指摘したいと思います(しゃれを意図しています)。ここに賛否両論を含む良い説明があります:http://www.haskell.org/haskellwiki/Pointfree