8

質問mapを使用して定義した後、次のことが頭に浮かびました。foldr

mapを使用して定義できる場合foldr、逆はどうでしょうか。

私の観点からは不可能ですが、適切な説明が見つかりません。助けてくれてありがとう!

4

3 に答える 3

15

いくつかの型シグネチャから始めましょう。

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

は普遍的な演算子であるため、mapを使用してシミュレートできます(これは、このプロパティに関するより数学的でありながら非常に友好的な論文です)。foldfold

mapをシミュレートするための創造的な方法があると確信していfoldrます。それは確かに楽しい運動になるでしょう。しかし、「クレイジーなポイントフリー」ではない単純な解決策はないと思います。それを説明するためにfoldr、しばらく忘れて、もっと単純な累積関数に集中しましょう。

sum :: [Int] -> Int

sum == foldr (+) 0、つまりfoldr実装しsumます。で実装できるならfoldrmap間違いなく で実装できsumますmap。私たちはそれを行うことができますか?

sumのシグネチャはクラッシュ ブローだと思います- をsum返し、Int常にmap何かのリストを返します。map重いものを持ち上げることができるかもしれませんが[a] -> a、最終的な結果を得るには、タイプの別の関数が必要です。この場合、 type の関数が必要[Int] -> Intです。それはまさに私たちが最初に避けようとしていたことなので、これは非常に残念です.

だから答えは次のとおりだと思います:foldr使用して実装できmapます-しかし、おそらく使用する必要がありますfoldr:)

于 2014-05-24T22:39:18.417 に答える
2

ある種の不正行為ヘルパー関数を作成する場合:

f [x] a = x a
f (x:xs) a = f xs (x a)

foldr g i xs = f (map g $ reverse xs) i
于 2014-05-24T22:36:33.073 に答える