質問map
を使用して定義した後、次のことが頭に浮かびました。foldr
map
を使用して定義できる場合foldr
、逆はどうでしょうか。
私の観点からは不可能ですが、適切な説明が見つかりません。助けてくれてありがとう!
質問map
を使用して定義した後、次のことが頭に浮かびました。foldr
map
を使用して定義できる場合foldr
、逆はどうでしょうか。
私の観点からは不可能ですが、適切な説明が見つかりません。助けてくれてありがとう!
いくつかの型シグネチャから始めましょう。
foldr :: (a -> b -> b) -> b -> [a] -> b
map :: (a -> b) -> [a] -> [b]
は普遍的な演算子であるため、map
を使用してシミュレートできます(これは、このプロパティに関するより数学的でありながら非常に友好的な論文です)。fold
fold
map
をシミュレートするための創造的な方法があると確信していfoldr
ます。それは確かに楽しい運動になるでしょう。しかし、「クレイジーなポイントフリー」ではない単純な解決策はないと思います。それを説明するためにfoldr
、しばらく忘れて、もっと単純な累積関数に集中しましょう。
sum :: [Int] -> Int
sum == foldr (+) 0
、つまりfoldr
実装しsum
ます。で実装できるならfoldr
、map
間違いなく で実装できsum
ますmap
。私たちはそれを行うことができますか?
sum
のシグネチャはクラッシュ ブローだと思います- をsum
返し、Int
常にmap
何かのリストを返します。map
重いものを持ち上げることができるかもしれませんが[a] -> a
、最終的な結果を得るには、タイプの別の関数が必要です。この場合、 type の関数が必要[Int] -> Int
です。それはまさに私たちが最初に避けようとしていたことなので、これは非常に残念です.
だから答えは次のとおりだと思います:foldr
使用して実装できmap
ます-しかし、おそらく使用する必要がありますfoldr
:)
ある種の不正行為ヘルパー関数を作成する場合:
f [x] a = x a
f (x:xs) a = f xs (x a)
foldr g i xs = f (map g $ reverse xs) i