1

type を持つ関数「パイプライン」を作成するように求められました。[a -> a] -> [a] -> [a]このようなパイプラインでは、元の関数リストの各関数が入力の各要素に順番に適用されます。たとえば、パイプライン[(+1),(*2),pred] [1,2,3]は を返し[1,3,5]ます。

ソリューション シートの答えは ですがpipeline = map . foldr (.) id、よくわかりません。この解決策はどのように実現できますか?

4

3 に答える 3

1

ひとつ考えられるのfoldrは、

foldr f z xs

すべての (:) を に置き換えxsf空のリストをに置き換えますz

ご了承ください

[(+1), (*2)]

の省略形です

(+1) : (*2) : []

あなたは今、何を見ることができるはずです

foldr (.) id   ((+1) : (*2) : [])

に評価します。そして、これで全体の表現が理解できるようになります。

于 2013-11-07T10:32:21.997 に答える
1

折り目は、実際には非常に単純ですが、どういうわけか非常に混乱します。:特に右の折り畳み: 基本的には、リスト内のそれぞれを代替の指定された関数に置き換え、リストをnilinit 値に置き換える以外に何もしません。あなたの例:

foldr (.) id [(+1),(*2),pred]
≡ foldr (.) id ( (+1) : (*2) : pred : [] )
≡                (+1) . (*2) . pred . id

したがって、これは単にリスト内のすべての関数を大きな構成にチェーンするだけです。

このチェーンを取得したら、それを別のリストのすべての値に適用するのは簡単で、map.

于 2013-11-07T10:32:32.670 に答える
0

問題の核心は type の関数を持つことです:[a -> a] -> (a -> a)つまり、関数のリストを 1 つの関数に変換します。

foldrタイプがあります:(b -> c -> c) -> c -> [b] -> c

タイプがどのように適合するかを見てみましょう。

  • (b -> c -> c) -> c -> [b] -> c
  • に置き換えbます(a -> a):((a -> a) -> c -> c) -> c -> [a -> a] -> c
  • に置き換えcます(a -> a):((a -> a) -> (a -> a) -> (a -> a)) -> (a -> a) -> [a -> a] -> (a -> a)
  • 関数の型は(.)です(b -> c) -> (a -> b) -> a -> c。これは、前の署名の最初の型にあるものです (私たちのものは all でしたa)。そこで使用できます(.)
  • 2 番目の部分では、関数(a -> a)を使用できidます。
  • これらを当てはめてみましょう:そして、私たちが必要としていた部分(.) idが残っています。[a -> a] -> (a -> a)
  • だから、私たちにfoldr (.) id与えます[a -> a] -> (a -> a)

その後、mapパーツは結果の関数をfoldrリストの各要素に適用するだけです。

注: 潜在意識がこれに慣れるまで、ホワイトボードを使用してこれらすべてを理解してください ;)

于 2013-11-07T10:49:08.283 に答える