Functor型クラス
fmapを実装
関数をf 値に作用する
Functor則を満たす
Functor型クラスの定義
code:hs
class Functor f where
fmap :: (a -> b) -> f a -> f b
fmapが定義されている
関数をf 値に作用する
インスタンスとなる型
kindが* → *になる型
型引数として具体型を唯一つとる型
List
fmapはmapと同じ
code:hs
instance Functor [] where
fmap = map
Maybe
code:hs
instance Functor Maybe where
fmap f (Just x) = Just (f x)
fmap f Nothing = Nothing
Either a
Either型コンストラクタは型引数を2つ取るので、そのうち1つを固定して部分適用した型がインスタンスになる
code:hs
instance Functor (Either a) where
fmap f (Right x) = Right (f x)
fmap f (Left x) = Left x
IO
code:hs
instance Functor IO where
fmap f action = do
result <- action
return (f result)
fはアクションを返す関数で、actionもアクションを渡すなにか
(->) r
fmapは関数合成を表す
fmapは(.)と同じ
code:hs
instance Functor ((->) r) where
fmap f g = (\x -> f (g x))
-- 以下のように書いても同じ
instance Functor ((->) r) where
fmap = (.)
モナド型クラスのインスタンスではないけどFunctorになる例
Data.Map
code:hs
fmap (+2) $ fromList ("a", 12), ("b", 13)
-- ("a", 14), ("b", 15)
fmapを使っている例
code:hs
fmap :: (a -> b) -> f a -> f b
-- List
fmap (*2) 1,2,3
map (*2) 1,2,3 -- これと同じ
-- Maybe
fmap (*3) (Just 3)
fmap (*3) Nothing
fmap (++ " world") (Just "hello")
-- Either
fmap (+ 12) (Right 12)
fmap (+ 12) (Left 12)
-- IO
fmap putStrLn getLine
fmap reverse getLine
fmap (++"!") getLine
-- ((->) r)
-- fmap (*3) (+100)
(fmap (*3) (+100)) 1
((*3) . (+100)) 1 -- これと同じ
最後の関数ファンクターの場合はfmap (*3) (+100)が、リストもなどで言うfmap (*3) [1,2,3]の形になっている
つまり、関数ファンクターの結果は関数である
なので、わかりやすく1を作用させて、fmap (*3) (+100) 1と書いている
リストやMaybeなどだけを見ると、Functorとは、「何かしらの値を包んだ文脈」のように捉えることが出来るが、IOや関数ファンクタを見てみるとそうでもないように見える
fの中身にa -> bの計算をし、その結果にfを修飾したもの、と考えると説明はつく
lifting
持ち上げ
fmapの型を以下のように捉える
fmap :: (a -> b) -> (f a -> f b)
a->bとf a -> f bという2つの関数を引数に取る2引数関数
<$>
$>
<&>
containersライブラリにある(Tree, Map, Sequence, Streamのような)沢山の標準の型はFunctorのインスタンスです。注意すべき例外はSetで、(数学的には確かにファンクタなのですが)HaskellではFunctorにすることができません。これは、Setが要素に対してOrd制約を必要とするからです。fmapはあらゆる型aとbに対して適用できなくてはなりません。 ref
fp-ts
https://dev.to/gcanti/getting-started-with-fp-ts-functor-36ek
fmapに加えてflapが用意されている
flap :: a -> f (a -> b) -> f b
Functorには2種類ある
fmapに現れる→が線形性を持っているかどうかで区別する
ref 線形型
a→bと書いた時に、aが1度だけ使われる場合は線形性があると言う
そのとき、a ⊸ bと表記する
Data Functor
https://www.tweag.io/blog/2020-01-16-data-vs-control/#data-functors
データのコンテナであるFuctor
複数の値を保持する
fmap :: (a ⊸ b) -> [a] ⊸ [b]
e.g. List
Control Functor
https://www.tweag.io/blog/2020-01-16-data-vs-control/#control-functors
結果をeffectでラップするFunctor
単一の値を含む
Effectに関するものである
fmap :: (a ⊸ b) ⊸ m a ⊸ m b
e.g. State
参考
すごいH本 7章
よんでない http://south37.hatenablog.com/entry/2014/03/25/Functorってなんですか?