2016-09-29 3 views
3

マップとfmapの違いは、後者が関数を返すことができるということです。マップと区別するためのFmapの例?

私はこのhttp://learnyouahaskell.comのファンクションセクションを勉強していますが、説明の一部は少し不明です。同様に、以下で

地図とFMAP振る舞い:

let exMap = map (+1) [1..5] 
let exFMap = fmap (+1) [1..5] 

機能を返すFMAPの良い例とは何ですか?

答えて

10

いいえ、違いはfmapが任意のファンクタに適用されることです。例えば:

readLine :: IO String   -- read a line 
fmap length readLine :: IO Int -- read a line and count its length 

Just 4 :: Maybe Int 
fmap (+10) (Just 4) :: Maybe Int -- apply (+10) underneath Just 
            -- returns (Just 14) 
map

(通常[a] -> [b]と記す)関数[] a -> [] ba -> bを回します。

fmapだけではなくf = []のために、任意の関手fのために機能f a -> f ba -> bになります。上記の例では、f = IOf = Maybeを選択しました。

+0

これをさらに進化させ、簡単な言葉で、ファンクターとアプリケーションファンクターとの違いを区別できますか? –

+1

'a-> b'と' f a'がある場合、 'f'がファンクタであるとき、' fmap'を使って 'fb'を得ることができます。しかし、 'f(a-> b)'と 'f a'を持っていれば、' f b'を得ることができません:関数は 'f'の下にラップされ、引数と相互作用する方法はありません。適用ファンクタは代わりに、追加操作「<*>」を定義します。 – chi

+0

利用可能なファンクタの1つは実際に関数に関連する "読者"ですが、今はそれを学ぶのに最適な段階ではないかもしれません – dfeuer

3
それは、各関数の型シグネチャを見て、あなたが見ている map機能を起動させるために役立つだろう

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

あなたが見ることができるように、このmap関数はリスト上で動作します。しかし、論理的には、マッピング可能な多くのデータ構造が存在します。他にも可能な地図は次のとおりです。

map :: (a -> b) -> Map k a -> Map k b 
map :: (a -> b) -> Maybe a -> Maybe b 
map :: (a -> b) -> IO a -> IO b 

これはちょうど氷山の一角です。多くのものをマップできます!

タイプクラスをサポートしていない言語では、これはあなたが知っている世界かもしれません。単にmap関数がたくさんあり、実際にはmapを区別するために適切なモジュールタイプで修飾する必要があります。ハスケルではそうではありません!

今度はfmapを見てみましょう:

fmap :: Functor f => (a -> b) -> f a -> f b 

この関数は、上に示したものとまったく同じ形式を持っていますが、ファンクタで何に取り組んでいます。

ファンクタは次のように定義されています

class Functor f where 
    fmap  :: (a -> b) -> f a -> f b 
    (<$)  :: a -> f b -> f a 
    (<$)  = fmap . const 

うまくいけば、これはファンクタは単純にオーバーマップされているサポート何かであること、それが明らかになります。

したがって、fmapが一般的であり、mapが特異的である。

+0

'Text'や' ByteString'で 'fmap'することはできませんが、 – chi

+0

@chi私はそれらをより良い例に置き換えようとします – TheInnerLight

+0

@TheInnerLightこれをデータ型のバイナリツリーに適用する例を与えることができますTree a = Empty | Node a(Tree a)(Tree a)? –

2

fmapより一般的です。mapよりも一般的です。実際にはリストには違いはありません。ここにはmap == fmapがあります。

は、私たちは、これは基本的にあなたが同じ形状が異なる要素のコンテナにコンテナを変換関数に簡単な関数を回すことができると言う fmap

class Functor f where 
    fmap :: (a -> b) -> (f a -> f b) 

の定義から始めましょう。

instance Functor [] where 
    fmap = map 

instance Functor Maybe where 
    fmap _ Nothing = Nothing 
    fmap f (Just something) = Just (f something) 

より多くのがありますが、私はほとんど単一の型パラメータを持つすべてのコンテナはあなたが

ため
data Tree a = Tree a [a] 

のインスタンスを定義しようとすることができます練習として数子

ことができると思いますfmapの使用は@ chiの答えを参照してください。

関連する問題