{-# LANGUAGE RankNTypes, InstanceSigs, DeriveFunctor #-}
newtype Cont a = Cont {
unCont :: forall r. (a -> r) -> r
}
(>>-) :: Cont a -> (a -> r) -> r
-- (Cont c) >>- f = c f
(>>-) = unCont
instance Functor Cont where
fmap :: forall a b. (a -> b) -> Cont a -> Cont b
fmap f (Cont c) = Cont $ \g -> c (\a -> g $ f a)
instance Applicative Cont where
pure :: forall a. a -> Cont a
pure x = Cont $ \c -> c x
(<*>) :: forall a b. Cont (a -> b) -> Cont a -> Cont b
(Cont f) <*> (Cont c) = Cont $ \g -> g (f c)
instance Monad Cont where
return = pure
-- cx >>= f = Cont $ \k ->
-- cx >>- \x ->
-- (f x) >>- \fx ->
-- k fx
Cont x >>= f = Cont $ \k -> x $ \y ->
let Cont h = f y
in h $ \ z -> k z
data Connection a = Connection a deriving (Show, Functor)
withConnection :: forall r. (Connection String -> r) -> r
withConnection f = f (Connection "MyConnection")
comp = fmap ("Modified" ++) <$> Cont withConnection
main = print $ unCont comp id