私が使用して試した、どこでもmap、fmapうまくとして働いています。Haskellの作成者はなぜmap関数の必要性を感じたのですか?それだけで、現在として知られているものであることができなかったfmapし、fmap言語から削除されるだろうか?
fmapます。Functorインスタンスに関数をマッピングすることです。に特化した目的はなんとおもいますかmap。
私が使用して試した、どこでもmap、fmapうまくとして働いています。Haskellの作成者はなぜmap関数の必要性を感じたのですか?それだけで、現在として知られているものであることができなかったfmapし、fmap言語から削除されるだろうか?
fmapます。Functorインスタンスに関数をマッピングすることです。に特化した目的はなんとおもいますかmap。
回答:
オーガストのコメントに注目するために答えたい:
それは実際にそれが起こる方法ではありません。起こったことは、マップのタイプがHaskell 1.3のFunctorをカバーするように一般化されたことです。つまり、Haskell 1.3ではfmapはmapと呼ばれていました。この変更はHaskell 1.4で元に戻され、fmapが導入されました。この変更の理由は教育的でした。初心者にHaskellを教えるとき、非常に一般的なタイプのマップはエラーメッセージを理解することをより難しくしました。私の意見では、これは問題を解決する正しい方法ではありませんでした。
Haskell 98は一部のHaskellers(私を含む)によって一歩後退したと見なされており、以前のバージョンではより抽象的で一貫性のあるライブラリが定義されていました。しかたがない。
map and fmap長い時間を回避されている-それは、2006年8月にはHaskellプライムメーリングリストで再加熱した- haskell.org/pipermail/haskell-prime/2006-August/thread.html。カウンターポイントとして、私は現状維持を好む。私にとって、ミランダにほぼ対応するHaskellのサブセットがあることは価値があるようです。英国では、ミランダはコンピュータサイエンスの学生だけでなく、数学の学生の教育言語としても使用されていました。そのニッチが非関数型言語(Mathematicaなど)でまだ失われていない場合、Haskellが統一された形でmap満たすことはありません。
https://wiki.haskell.org/Typeclassopedia#FunctorのFunctorドキュメントからの引用
別の
map関数が必要な理由を尋ねるかもしれません。現在のリストのみのmap関数を廃止し、 代わりに名前fmapを変更しmapないのはなぜですか?まあ、それは良い質問です。通常の議論は、Haskellを学んだばかりの人は、map間違って使用すると、リストについてのエラーではなく、についてのエラーが表示されるということFunctorです。
アプリケーションサイトでは同じように見えますが、もちろん異なります。これら2つの関数、mapまたはのいずれかをfmap値のリストに適用すると、同じ結果が得られますが、同じ目的のためのものではありません。
GHCIセッション(Glasgow Haskell Compiler Interactive)を実行して、これら2つの関数に関する情報を照会し、それらの実装を確認すると、多くの違いが見つかります。
GHCIに問い合わせて map
Prelude> :info map
map :: (a -> b) -> [a] -> [b] -- Defined in ‘GHC.Base’
これは、任意の型aの値のリストを生成する任意の型の値のリストに適用可能な高次関数として定義されていることがわかりますb。(多型がa及びb任意のタイプのための上記定義のスタンドに)map機能に適用されることが意図されている値のリストのHaskellに他の多くの中ただ一つの可能なデータ型です。mapこの関数は、値のリストではない何かに適用することができませんでした。
GHC.Baseソースコードから読み取れるmapように、関数は次のように実装されています
map _ [] = []
map f (x:xs) = f x : map f xs
これは、パターンマッチングを使用してリストの先頭(the x)を末尾(the xs)から引き離し、:(cons)値コンストラクターを使用して新しいリストを作成して、先頭に追加しますf x(「fをxに適用」と読みます)。mapリストが空になるまで、尾の上の再帰へ。map関数の実装が他の関数に依存するのではなく、それ自体に依存することは注目に値します。
次に、情報についてクエリを実行するfmapと、まったく異なるものが表示されます。
Prelude> :info fmap
class Functor (f :: * -> *) where
fmap :: (a -> b) -> f a -> f b
...
-- Defined in ‘GHC.Base’
今回fmapは、Functor型クラスに属したいデータ型によって実装を提供する必要がある関数の1つとして定義されます。つまり、「値のリスト」データ型だけでなく、fmap関数の実装を提供できる複数のデータ型が存在する可能性があります。これはfmap、はるかに大きなデータ型のセットに適用できます。
GHC.Baseソースコードから読み取れるように、fmap関数の可能な実装は、Maybeデータ型によって提供されるものです。
instance Functor Maybe where
fmap _ Nothing = Nothing
fmap f (Just a) = Just (f a)
もう1つの可能な実装は、2タプルデータ型によって提供されるものです。
instance Functor ((,) a) where
fmap f (x,y) = (x, f y)
もう1つの可能な実装は、リストデータ型によって提供されるものです(もちろん!)。
instance Functor [] where
fmap f xs = map f xs
これはmap関数に依存しています。
map一方、関数は(値は任意のタイプである)値のリスト以外の何ものにも適用できるfmap機能は多くのデータ型を適用することができます:ファンクタクラスに属しているもの(例えばmaybes、タプル、リストなどのすべて)。以来、「値のリスト」、次いで(それのための実装を提供するため)データ型はファンクタでもありfmap、ならびに非常に同じ結果を生成しているにも適用することができますmap。
map (+3) [1..5]
fmap (+3) (Just 15)
fmap (+3) (5, 7)