Skip to content

Instantly share code, notes, and snippets.

@plaidfinch
Created February 7, 2015 22:20
Show Gist options
  • Save plaidfinch/fb9d8b0fe69d6e20c345 to your computer and use it in GitHub Desktop.
Save plaidfinch/fb9d8b0fe69d6e20c345 to your computer and use it in GitHub Desktop.
The Coöperational Comonad
{-# LANGUAGE GADTs #-}
module Cooperational where
import Control.Monad
import Control.Applicative
import Control.Comonad
data Oper f a =
Return a
| forall b. Bind (f b) (b -> Oper f a)
data Coop f a =
Coop { extract_ :: a
, extend_ :: forall b. (Coop f a -> b) -> f b }
instance Functor (Oper f) where
fmap f x = case x of
Return a -> Return (f a)
Bind a g -> Bind a (fmap f . g)
instance Functor (Coop f) where
fmap f a =
Coop { extract_ = f (extract_ a)
, extend_ = \g -> extend_ a (g . fmap f) }
instance Monad (Oper f) where
return = Return
x >>= f = case x of
Return a -> f a
Bind a g -> Bind a (g >=> f)
instance Comonad (Coop f) where
extract = extract_
extend f a =
Coop { extract_ = f a
, extend_ = \g -> extend_ a (f =>= g) }
instance Applicative (Oper f) where
pure = return
(<*>) = ap
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment