まあ、のはcurried functionfoldr
ための型シグネチャを見てみましょう:だから
>:t foldr
foldr :: (a -> b -> b) -> b -> [a] -> b
foldr
はバイナリ関数を受け取り(すなわちa->b->b
)、b
値、a
値のリスト、および返しますb
値。
するのは、より明確な定義を取得するためのfoldr
documentationを見てみましょう:
foldrを、二項演算子、開始値(オペレータの通常 右アイデンティティ)に適用され、
をそれでは、myConcat xs = foldr (++) []
のための型シグネチャを見てみましょう:リストには、右から左へ、 二項演算子を使用してリストを削減します
> :t myConcat
myConcat :: t -> [[a]] -> [a]
うーん...それは我々が望んでいないのです...
問題は、あなたがタイプ[a]
のfoldr
値を提供したことがないということです。だから今、myConcat
はタイプ[a]
の値は以下のように、foldr (++) []
を完了するために、xs
とを満たすために、どのようなタイプの、いくつかの値を必要とします:作品
> myConcat 2 [[1,2],[3,4]]
[1,2,3,4]
> myConcat Nothing [[1,2],[3,4]]
[1,2,3,4]
が、最初の引数は無駄です。しかし
、我々は同様に、foldr (++) []
にかけてそのxs
値を渡す場合:
myConcat xs = foldr (++) [] xs
とそのタイプの署名をチェック
> :t myConcat
myConcat :: [[a]] -> [a]
はるかに良いああ、。これで、myConcatはxs
を使用してfoldr
関数を完了します。
また、myConcat = foldr (++) []
も機能し、実際にはpoint-free style programmingの例です。我々はfoldr (++) []
、
> :t foldr (++) []
foldr (++) [] :: [[a]] -> [a]
の型シグネチャをチェックすると、我々はすでにpartial applicationを通じてfoldr
その最初の二つの引数を提供しているので、我々は機能を得るバックという意志が[[a]]
値を取り、我々がやりたいです!だから、名前に代入するだけです。上の例のように動作しますが、明示的に引数を渡す必要はありません!
> let myConcat = foldr (++) []
> :t myConcat
myConcat :: [[a]] -> [a]
> myConcat [[1,2],[3,4]]
[1,2,3,4]
+1:非常に分かりやすい説明。万が一ハスケル関連のブログを持っているのですか?私はあなたのスタイルが好きです。 :-) –
@Frerich Raabe:ありがとう!実際に私はScalaを中心にしたブログを持っていますが、現在はHaskellにもかかわらず、残念ながらそれはドイツ語です:http://dgronau.wordpress。com/ – Landei
本当にありがとう、私は今理解している:)偉大な説明 – Adi