# HG changeset patch # User Yasutaka Higa # Date 1409648598 -32400 # Node ID 309850f23a679232bfd20043dbe9c2f5bb1a24c7 # Parent ecb53fc23f6f73e02d2933a7d80ae860621bf919 Update slide diff -r ecb53fc23f6f -r 309850f23a67 slides/20140902/slide.md --- a/slides/20140902/slide.md Tue Sep 02 17:46:13 2014 +0900 +++ b/slides/20140902/slide.md Tue Sep 02 18:03:18 2014 +0900 @@ -30,6 +30,8 @@ data Similar a a = Similar a (a -> a) a ``` +* 型変数をどう扱うかで悩み中です + # Usage : Similar Monad ``` initObj = Similar 100 id 100 @@ -47,23 +49,70 @@ fmap g (Similar a f b) = Similar a (g . f) $ g b ``` -* こんな感じなんだろうけれど Monad の return が定義できない +* 型変数が2つだと Functor の定義は楽 + +# Similar Monad as Functor +``` +instance Monad (Similar a) where + return x = Similar x id x -- NG + s >>= f = mu (eqmap f s) +``` +* 型変数が2つだと Monad の return が定義できない * (Similar a) の a を固定していないと Monad の instance にできない * return :: a1 -> Similar a a1 * を想定されているが、 id なので Similar a a でおかしい -# Sample : Similar Monad as Functor +# Sample : Similar Monad as Functor (revision 9) ``` similar :: (Show b, Eq b) => (a -> b) -> (a -> b) -> a -> b similar f g x = same $ Similar x g (f x) --- samples (revision 9) +-- samples ok = map (similar twicePlus double) [1..10] notOk = map (similar twicePlus plusTwo) [1..10] okSpecific = map (similar twicePlus plusTwo) [2] ``` -# 謎 + +# Similar Monad as Monad +``` +data Similar a b = Similar a (a -> b) b + +instance EqMonad Similar where + return x = Similar x id x + s >>= f = mu (eqmap f s) +``` + +* 型変数が1つなら Monad の定義はできる +* 通常の Functor だと (a -> b) の b に constraint をかけられない + + +# Similar Monad as Monad + +``` +class EqFunctor f where + eqmap :: (Eq a, Eq b) => (a -> b) -> f a -> f b + +instance EqFunctor Similar where + eqmap f s = Similar fs id fs + where fs = f $ same s +``` + +* (a -> b) の b が Eq 保証された Functor Class を使えばどうにか + +# Sample : Similar Monad as Monad (revision 11) +``` +same $ return 100 >>= (\x -> Similar x twicePlus $ double x) +200 + +same $ return 2 >>= (\x -> Similar x plusTwo $ double x) +4 + +same $ return 100 >>= (\x -> Similar x plusTwo $ double x) +*** Exception: Prelude.undefined +``` + +# Problem * type variable が 1つだと * Functor で移す先が Eq である保証が無くて怒られる * type variable が 2つだと