-- Class Declarations class {- record -} ToMaybe m where { toMaybe :: m a -> Maybe a; }; class {- variant -} MyMonad m => ContMonad m r | m -> r where { callCC :: ((a -> m b) -> m a) -> m a; mkCont :: ((a -> r) -> r) -> m a; }; class {- variant -} MyMonad m where { unit :: a -> m a; bind :: m b -> (b -> m a) -> m a; }; class {- record -} ToCont m r | m -> r where { toCont :: m a -> (a -> r) -> r; }; -- Data Declarations data Data''0 r a = C''unit''0 a | forall b . C''bind''0 (Data''0 r b) (b -> Data''0 r a) | forall c . C''callCC''0 ((a -> Data''0 r c) -> Data''0 r a) | C''mkCont''0 ((a -> v1) -> v1); {- -- using GADT-style declaration data Data''0 r a where { C''unit''0 :: a -> Data''0 r a; C''bind''0 :: Data''0 r b -> (b -> Data''0 r a) -> Data''0 r a; C''callCC''0 :: ((a -> Data''0 r c) -> Data''0 r a) -> Data''0 r a; C''mkCont''0 :: ((a -> v1) -> v1) -> Data''0 r a; }; -} -- Instance Declarations instance ToCont (Data''0 r) r where { toCont (C''unit''0 a) = \ c -> c a; toCont (C''bind''0 m k) = \ c -> toCont m (\ a -> toCont (k a) c); toCont (C''mkCont''0 m) = m; toCont (C''callCC''0 h) = \ c -> let {k = \ a -> mkCont (\ d -> c a);} in toCont (h k) c; }; instance MyMonad (Data''0 r) where { unit = C''unit''0; bind = C''bind''0; }; instance ContMonad (Data''0 r) r where { callCC = C''callCC''0; mkCont = C''mkCont''0; }; -- Cast(?) Declarations id''0 :: Data''0 r Int -> Data''0 r Int; id''0 x = x; -- BindGroups bar = toCont (id''0 (callCC (\ k -> bind (unit 1) (\ x -> k 2))));