Coyoneda
Yonedaの双対
「kindが*->*の抽象データ型」からFunctor型クラスを生成する
#WIP
圏論
https://mbps.hatenablog.com/entry/2014/09/30/150836
https://mbps.hatenablog.com/entry/2014/04/12/074615
https://mbps.hatenablog.com/entry/2014/04/04/044134
https://mbps.hatenablog.com/entry/2014/04/05/002411
https://mbps.hatenablog.com/entry/2015/02/28/055025
https://ncatlab.org/nlab/show/co-Yoneda+lemma
Coyonedaは、Functorをdata構造として表現したもの
hs
code:hs
data Coyoneda f b = forall a. Coyoneda (a -> b) (f a)
-- GATD
data Coyoneda f b where
Coyoneda :: (a -> b) -> f a -> Coyoneda f b
instance Functor (Coyoneda f) where
fmap f (Coyoneda g fb) = Coyoneda (f . g) fb
上のようにGADTで定義すると、fmapとほぼ同じ見た目をしていることがわかりやすい
code:hs
fmap :: (a -> b) -> f a -> f b
purs
https://pursuit.purescript.org/packages/purescript-free/4.0.0/docs/Data.Coyoneda
code:purs(hs)
newtype Coyoneda f a = Coyoneda (Exists (CoyonedaF f a))
data CoyonedaF f a i = CoyonedaF (i -> a) (f i)
https://its-out-of-tune.hatenadiary.org/entry/20130601/1370109743
https://ryota-ka.hatenablog.com/entry/2018/07/03/021216
https://qiita.com/goldarn_ring/items/1c895292ae313b74a410
コメント
https://myuon-myon.hatenablog.com/entry/2017/04/29/213512
https://qiita.com/YoshikuniJujo/items/729ad9830833eacb9d75
https://ncatlab.org/nlab/show/free+functor
Free Functor
https://hackage.haskell.org/package/free-functors
ここで、CoyonedaはFree Functorと言えそう、と書いてて確かに、と思ったが、「Free Functor」という概念は実際あるみたい
ただこれがCoyonedaと同じようなものを指しているのかどうかは読んでないので知らん
ユースケース
Free+CoYonedaが、Operationalモナド
「*->*の任意のデータ型」と「Coyoneda」と「Freeモナド」を組み合わせれば手軽にMonadを作ることが出来る
Day convolution
https://ncatlab.org/nlab/show/Day+convolution
https://twitter.com/fumieval/status/576349394724765697
code:hs
newtype Natural f g = Natural (forall x. f x -> g x)
yoneda :: Functor f => f a -> Natural ((->) a) f
yoneda f = Natural $ \ax -> fmap ax f
code:hs
data Proc a = Action1 a | Action2 a | Action3 a
act1 = Free $ Coyoneda id (Action1 (Pure ()))
act2 = Free $ Coyoneda id (Action2 (Pure ()))
act3 = Free $ Coyoneda id (Action3 (Pure ()))
runProc :: Free (Coyoneda Proc) () -> IO ()
runProc (Pure ()) = putStrLn "end"
runProc (Free (Coyoneda f act)) = case act of
Action1 a -> putStrLn "act1" >> runProc (f a)
Action2 a -> putStrLn "act2" >> runProc (f a)
Action3 a -> putStrLn "act3" >> runProc (f a)
proc :: Free (Coyoneda Proc) ()
proc = do
act1
act2
act3
main = runProc proc
/tosuke/Coyoneda