packages feed

for-free (empty) → 0.1

raw patch · 3 files changed

+794/−0 lines, 3 filesdep +basedep +comonaddep +comonad-transformerssetup-changed

Dependencies added: base, comonad, comonad-transformers, containers, contravariant, transformers

Files

+ Control/ForFree.hs view
@@ -0,0 +1,735 @@+{-
+ Examples of similar types:
+
+ Co (Env x) = Reader x
+ Co Initialize = Finalize
+ Co (Store x) = State x
+ Co (Traced x) = Writer x
+ Codensity (Const x) = Cont x
+ Codensity Endo = []
+ CodensityAsk ((->) x) = Either x
+ CodensityAsk (Const x) = ((->) x)
+ CodensityAsk Endo = Writer (Sum Natural)
+ CodensityAsk Finalize = Identity
+ CodensityAsk Identity = Maybe
+ CodensityAsk Predicate = Data.Searchable.Set (infinite-search)
+ Cofree (Const x) = Env x
+ Cofree Finalize = Identity
+ Free (Const x) = Either x
+ Free Finalize = Maybe
+ Free Initialize = Identity
+-}
+
+{-# LANGUAGE EmptyDataDecls #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE GADTs #-}
+{-# LANGUAGE KindSignatures #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+-- {-# LANGUAGE OverlappingInstances #-}
+{-# LANGUAGE Rank2Types #-}
+{-# LANGUAGE StandaloneDeriving #-}
+{-# LANGUAGE UndecidableInstances #-}
+
+module Control.ForFree (
+  -- * Plus
+    Plus(..), OpT(..),
+  -- * Yoneda
+    Yoneda(..), unreduceYoneda,
+  -- * CoYoneda
+    CoYoneda(..), reduceCoYoneda,
+  -- * Free monad
+    Free(..), reduceFree, affectFree, FreeT(..), reduceFreeT,
+  -- * Free comonad
+    Cofree(..), unreduceCofree, affectCofree, CofreeT(..),
+    unreduceCofreeT,
+  -- * Codensity monad
+    Codensity(..), lowerCodensity,
+  -- * Density comonad
+    Density(..), liftDensity,
+  -- * Monads from comonads
+    CoT(..), Co, runCo, liftCoT0, lowerCoT0, lowerCo0, liftCoT1,
+    lowerCoT1, lowerCo1,
+  -- * Codensity ask monad
+    CodensityAsk(..), peekCodensityAsk, CodensityAskT(..),
+    peekCodensityAskT, lowerCodensityAskT, catchCodensityAsk,
+    catchCodensityAskT,
+  -- * Density ask comonad
+    DensityAskT(..), DensityAsk, liftDensityAsk,
+  -- * Miscellaneous
+    Finalize(..), Initialize(..), Decompose(..), Recompose(..),
+  -- * Instances of types from other modules
+    Op(..), Endo(..), Const(..)
+) where {
+
+  import Control.Applicative;
+  import Control.Arrow;
+  import Control.Category;
+  import Control.Comonad;
+  import Control.Comonad.Hoist.Class;
+  import Control.Comonad.Trans.Class;
+  import Control.Monad;
+  import Control.Monad.Trans.Class;
+  import Control.Monad.Trans.Maybe (MaybeT);
+  import Control.Monad.Trans.Reader (ReaderT(..));
+  import Control.Monad.Trans.RWS (RWST);
+  import Control.Monad.Trans.State (StateT);
+  import Control.Monad.Trans.Writer (WriterT(..));
+  import Data.Functor.Contravariant;
+  import Data.Functor.Identity;
+  import Data.IntMap (IntMap);
+  import Data.Map (Map);
+  import Data.Monoid;
+  import Data.Sequence (Seq);
+  import Prelude hiding (id, (.));
+
+  instance Monoid x => Alternative (Const x) where {
+    empty = Const mempty;
+    Const x <|> Const y = Const (mappend x y);
+  };
+
+  instance Monoid x => Plus (Const x) where {
+    zero = Const mempty;
+    plus (Const x) (Const y) = Const (mappend x y);
+  };
+
+--  instance Category Op where {
+--    id = Op id;
+--    Op x . Op y = Op (y . x);
+--  };
+
+-- | Like 'Op' but apply another type.
+;
+  newtype OpT f a b = OpT { getOpT :: f b -> a };
+
+  instance Functor f => Contravariant (OpT f x) where {
+    contramap f (OpT x) = OpT (x . fmap f);
+  };
+
+  instance Comonad f => Category (OpT f) where {
+    id = OpT extract;
+    OpT x . OpT y = OpT (y =<= x);
+  };
+
+-- | 'zero' and 'plus' should form a monoid.
+;
+  class Plus f where {
+    zero :: f x;
+    plus :: f x -> f x -> f x;
+  };
+
+--  instance Alternative f => Plus f where {
+--    zero = empty;
+--    plus = (<|>);
+--  };
+
+  instance Plus Endo where {
+    zero = mempty;
+    plus = mappend;
+  };
+
+  instance Monoid x => Plus (Op x) where {
+    zero = Op (const mempty);
+    plus (Op x) (Op y) = Op (liftA2 mappend x y);
+  };
+
+  instance Monoid x => Plus (OpT f x) where {
+    zero = OpT (const mempty);
+    plus (OpT x) (OpT y) = OpT (liftA2 mappend x y);
+  };
+
+  instance Plus Comparison where {
+    zero = Comparison (\_ _ -> EQ);
+    plus (Comparison x) (Comparison y) = Comparison (\a b -> mappend (x a b) (y a b));
+  };
+
+-- | Right Yoneda lemma
+;
+  newtype Yoneda f x = Yoneda { runYoneda :: forall z. (x -> z) -> f z };
+
+  instance Functor (Yoneda f) where {
+    fmap f (Yoneda x) = Yoneda (\k -> x (k . f));
+  };
+
+  instance Plus f => Plus (Yoneda f) where {
+    zero = Yoneda (const zero);
+    plus (Yoneda x) (Yoneda y) = Yoneda (liftA2 plus x y);
+  };
+
+-- | Build the right Yoneda by specifying the translation from a functor to anything.
+;
+  unreduceYoneda :: Functor w => (forall z. w z -> f z) -> w x -> Yoneda f x;
+  unreduceYoneda f x = Yoneda (\z -> f (z <$> x));
+
+-- | Left Yoneda lemma
+;
+  data CoYoneda f x = forall z. CoYoneda (z -> x) (f z);
+
+  instance Functor (CoYoneda f) where {
+    fmap f (CoYoneda x y) = CoYoneda (f . x) y;
+  };
+
+-- | Lower the left Yoneda by specifying the translation from the inner type to any functor.
+;
+  reduceCoYoneda :: Functor m => (forall z. f z -> m z) -> CoYoneda f x -> m x;
+  reduceCoYoneda f (CoYoneda x y) = x <$> f y;
+
+-- | Free monad from a functor
+;
+  data Free f x = Pure x | Free (f (Free f x));
+
+  deriving instance (Eq (f (Free f a)), Eq a) => Eq (Free f a);
+  deriving instance (Ord (f (Free f a)), Ord a) => Ord (Free f a);
+  deriving instance (Read (f (Free f a)), Read a) => Read (Free f a);
+  deriving instance (Show (f (Free f a)), Show a) => Show (Free f a);
+
+  instance Functor f => Functor (Free f) where {
+    fmap f (Pure x) = Pure (f x);
+    fmap f (Free x) = Free (fmap f <$> x);
+  };
+
+  instance Functor f => Applicative (Free f) where {
+    pure = Pure;
+    Pure a <*> Pure b = Pure (a b);
+    Pure a <*> Free b = Free (fmap a <$> b);
+    Free a <*> b = Free ((<*> b) <$> a);
+  };
+
+  instance Functor f => Monad (Free f) where {
+    return = Pure;
+    Pure a >>= f = f a;
+    Free m >>= f = Free ((>>= f) <$> m);
+  };
+
+  joinFree :: Functor f => Free f (Free f x) -> Free f x;
+  joinFree (Pure x) = x;
+  joinFree (Free x) = Free (join <$> x);
+  -- {-# RULES "join=joinFree" join = joinFree #-};
+
+  instance (Functor f, Plus f) => Alternative (Free f) where {
+    empty = Free zero;
+    Pure x <|> _ = Pure x;
+    _ <|> Pure x = Pure x;
+    Free x <|> Free y = Free (plus x y);
+  };
+
+  instance (Functor f, Plus f) => MonadPlus (Free f) where {
+    mzero = empty;
+    mplus = (<|>);
+  };
+
+  instance Plus f => Plus (Free f) where {
+    zero = Free zero;
+    plus (Pure x) _ = Pure x;
+    plus _ (Pure x) = Pure x;
+    plus (Free x) (Free y) = Free (plus x y);
+  };
+
+  instance ComonadHoist Free where {
+    cohoist (Pure x) = Pure x;
+    cohoist (Free x) = Free (pure . cohoist $ extract x);
+  };
+
+-- | Lowers the free monad to another monad by giving the translation from the functor to the monad.
+;
+  reduceFree :: Monad m => (forall z. f z -> m z) -> Free f x -> m x;
+  reduceFree f (Pure x) = return x;
+  reduceFree f (Free x) = f x >>= reduceFree f;
+
+-- | Affect each level of the structure and pass a result of reading them to the leaf nodes.
+;
+  affectFree :: Functor g => (forall z. (s, f z) -> g (s, z)) -> (s, Free f x) -> Free g (s, x);
+  affectFree _ (s, Pure x) = Pure (s, x);
+  affectFree f (s, Free x) = Free (w f $ f (s, x)) where {
+    w :: Functor g => (forall z. (s, f z) -> g (s, z)) -> g (s, Free f x) -> g (Free g (s, x));
+    w f' x' = affectFree f' <$> x';
+  };
+
+-- | Free comonad from a functor
+;
+  data Cofree f x = x :< f (Cofree f x);
+  infixr 5 :<;
+
+  deriving instance (Eq (f (Cofree f a)), Eq a) => Eq (Cofree f a);
+  deriving instance (Ord (f (Cofree f a)), Ord a) => Ord (Cofree f a);
+  deriving instance (Read (f (Cofree f a)), Read a) => Read (Cofree f a);
+  deriving instance (Show (f (Cofree f a)), Show a) => Show (Cofree f a);
+
+  instance Functor f => Functor (Cofree f) where {
+    fmap f (x :< y) = f x :< (fmap f <$> y);
+  };
+
+  instance Functor f => Extend (Cofree f) where {
+    duplicate z@(x :< y) = z :< (duplicate <$> y);
+  };
+
+  instance Functor f => Comonad (Cofree f) where {
+    extract (x :< _) = x;
+  };
+
+  instance Applicative f => Applicative (Cofree f) where {
+    pure x = x :< pure (pure x);
+    (f :< fs) <*> (a :< as) = f a :< ((<*>) <$> fs <*> as);
+    (f :< fs) <* (_ :< as) = f :< ((<*) <$> fs <*> as);
+    (_ :< fs) *> (a :< as) = a :< ((*>) <$> fs <*> as);
+  };
+
+  instance ComonadHoist Cofree where {
+    cohoist (x :< y) = x :< (pure . cohoist $ extract y);
+  };
+
+-- | Make up the 'Cofree' structure by unfolding it.
+;
+  unfold :: Functor f => (b -> (a, f b)) -> b -> Cofree f a;
+  unfold f = uncurry (:<) . second (fmap $ unfold f) . f;
+
+-- | Build the free comonad from a comonad by giving the translation from the comonad to a functor.
+;
+  unreduceCofree :: Comonad w => (forall z. w z -> f z) -> w x -> Cofree f x;
+  unreduceCofree f x = extract x :< f (x =>> unreduceCofree f);
+
+-- | Affect each level of the structure and pass a result of reading them to each node.
+;
+  affectCofree :: Functor g => (forall z. (s, f z) -> g (s, z)) -> (s, Cofree f x) -> Cofree g (s, x);
+  affectCofree f (s, x :< y) = (s, x) :< w f (f (s, y)) where {
+    w :: Functor g => (forall z. (s, f z) -> g (s, z)) -> g (s, Cofree f x) -> g (Cofree g (s, x));
+    w f' x' = affectCofree f' <$> x';
+  };
+
+-- | Transformer of free monad.
+;
+  newtype FreeT f m r = FreeT { runFreeT :: m (Either r (f (FreeT f m r))) };
+
+  instance (Functor f, Functor m) => Functor (FreeT f m) where {
+    fmap f (FreeT x) = FreeT ((f +++ fmap (fmap f)) <$> x);
+  };
+
+  instance (Functor f, Monad m) => Monad (FreeT f m) where {
+    return = FreeT . return . Left;
+    FreeT m >>= f = FreeT (m >>= either (runFreeT . f) (return . Right . fmap (>>= f)));
+  };
+
+  joinFreeT :: (Functor f, Monad m) => FreeT f m (FreeT f m x) -> FreeT f m x;
+  joinFreeT (FreeT x) = FreeT (x >>= either runFreeT (return . Right . fmap join));
+  -- {-# RULES "join=joinFreeT" join = joinFreeT #-};
+
+  instance (Functor f, Applicative m, Monad m) => Applicative (FreeT f m) where {
+    pure = return;
+    (<*>) = ap;
+  };
+
+  instance (Functor f, MonadPlus m) => MonadPlus (FreeT f m) where {
+    mzero = FreeT mzero;
+    mplus (FreeT x) (FreeT y) = FreeT (mplus x y);
+  };
+
+  instance (Functor f, Monad m, Alternative m) => Alternative (FreeT f m) where {
+    empty = FreeT empty;
+    FreeT x <|> FreeT y = FreeT (x <|> y);
+  };
+
+  instance Plus m => Plus (FreeT f m) where {
+    zero = FreeT zero;
+    plus (FreeT x) (FreeT y) = FreeT (plus x y);
+  };
+
+  instance MonadTrans (FreeT f) where {
+    lift = FreeT . liftM Left;
+  };
+
+-- | As 'reduceFree' for transformers (you must reduce to the monad being transformed).
+;
+  reduceFreeT :: Monad m => (forall z. f z -> m z) -> FreeT f m x -> m x;
+  reduceFreeT f (FreeT x) = x >>= either return (f >=> reduceFreeT f);
+
+  data CofreeT f w x = CofreeT (w x) (f (CofreeT f w x));
+--  data CofreeT f w x = CofreeT (w (x, f (CofreeT f w x)));
+
+  instance (Functor f, Functor w) => Functor (CofreeT f w) where {
+    fmap f (CofreeT x y) = CofreeT (f <$> x) (fmap f <$> y);
+  };
+
+  instance (Functor f, Extend w) => Extend (CofreeT f w) where {
+    duplicate (CofreeT x y) = CofreeT (x =>> flip CofreeT y) (duplicate <$> y);
+  };
+
+  instance (Functor f, Comonad w) => Comonad (CofreeT f w) where {
+    extract (CofreeT x _) = extract x;
+  };
+
+  instance ComonadTrans (CofreeT f) where {
+    lower (CofreeT x _) = x;
+  };
+
+-- | As 'unreduceCofree' for transformers (you must unreduce from the comonad being transformed).
+;
+  unreduceCofreeT :: Comonad w => (forall z. w z -> f z) -> w x -> CofreeT f w x;
+  unreduceCofreeT f x = CofreeT x (f (x =>> unreduceCofreeT f));
+
+-- | Codensity monad from anything (it doesn't have to be a functor)
+;
+  newtype Codensity f x = Codensity { runCodensity :: forall z. (x -> f z) -> f z };
+
+  instance Functor (Codensity f) where {
+    fmap f (Codensity x) = Codensity (\k -> x (k . f));
+  };
+
+  instance Monad (Codensity f) where {
+    return x = Codensity ($ x);
+    m >>= k = Codensity (\c -> runCodensity m (\a -> runCodensity (k a) c));
+  };
+
+  instance Applicative (Codensity f) where {
+    pure x = Codensity ($ x);
+    (<*>) = ap;
+  };
+
+  instance Plus f => Alternative (Codensity f) where {
+    empty = Codensity (const zero);
+    Codensity x <|> Codensity y = Codensity (liftA2 plus x y);
+  };
+
+  instance Plus f => MonadPlus (Codensity f) where {
+    mzero = Codensity (const zero);
+    mplus (Codensity x) (Codensity y) = Codensity (liftA2 plus x y);
+  };
+
+  instance Plus f => Plus (Codensity f) where {
+    zero = mzero;
+    plus = mplus;
+  };
+
+  instance MonadTrans Codensity where {
+    lift x = Codensity (x >>=);
+  };
+
+-- | You can reduce the codensity monad of any applicative functor to that applicative functor.
+;
+  lowerCodensity :: Applicative f => Codensity f x -> f x;
+  lowerCodensity (Codensity x) = x pure;
+
+-- | Density comonad from anything (it doesn't have to be a functor)
+;
+  data Density f x = forall z. Density (f z -> x) (f z);
+
+  instance Functor (Density f) where {
+    fmap f (Density x y) = Density (f . x) y;
+  };
+
+  instance Extend (Density f) where {
+    duplicate (Density f x) = Density (Density f) x;
+  };
+
+  instance Comonad (Density f) where {
+    extract (Density f x) = f x;
+  };
+
+  instance Applicative f => Applicative (Density f) where {
+    pure x = Density (const x) (pure ());
+    Density f x <*> Density a y = Density (\k -> f (fst <$> k) (a (snd <$> k))) (liftA2 (,) x y);
+  };
+
+  instance ComonadTrans Density where {
+    lower (Density f x) = x =>> f;
+  };
+
+-- | You can make the density comonad from any copointed functor.
+;
+  liftDensity :: Comonad w => w a -> Density w a;
+  liftDensity = Density extract;
+
+  newtype CodensityAskT w m x = CodensityAskT { runCodensityAskT :: forall z. w (m z) -> (x -> m z) -> m z };
+
+-- | Codensity monad taking a parameter holding something related to the output type. If this parameter is a comonad, you get a 'MonadPlus'.
+;
+  newtype CodensityAsk w x = CodensityAsk { runCodensityAsk :: forall z. w z -> (x -> z) -> z };
+
+  instance Functor (CodensityAskT w m) where {
+    fmap f (CodensityAskT x) = CodensityAskT (\q k -> x q (k . f));
+  };
+
+  instance Monad (CodensityAskT w m) where {
+    return x = CodensityAskT (\_ f -> f x);
+    CodensityAskT m >>= f = CodensityAskT (\q k -> m q (\a -> runCodensityAskT (f a) q k));
+  };
+
+  instance Comonad w => MonadPlus (CodensityAskT w m) where {
+    mzero = CodensityAskT (\q _ -> extract q);
+    mplus (CodensityAskT f) (CodensityAskT g) = CodensityAskT $ flip (\y -> flip f y =<= flip g y);
+  };
+
+  instance Applicative (CodensityAskT w f) where {
+    pure = return;
+    (<*>) = ap;
+  };
+
+  instance Comonad w => Alternative (CodensityAskT w f) where {
+    empty = CodensityAskT (\q _ -> extract q);
+    CodensityAskT f <|> CodensityAskT g = CodensityAskT $ flip (\y -> flip f y =<= flip g y);
+  };
+
+  instance Comonad w => Plus (CodensityAskT w f) where {
+    zero = empty;
+    plus = (<|>);
+  };
+
+  instance MonadTrans (CodensityAskT w) where {
+    lift x = CodensityAskT (\_ f -> x >>= f);
+  };
+
+  instance Functor (CodensityAsk w) where {
+    fmap f (CodensityAsk x) = CodensityAsk (\q k -> x q (k . f));
+  };
+
+  instance Monad (CodensityAsk w) where {
+    return x = CodensityAsk (\_ f -> f x);
+    CodensityAsk m >>= f = CodensityAsk (\q k -> m q (\a -> runCodensityAsk (f a) q k));
+  };
+
+  instance Comonad w => MonadPlus (CodensityAsk w) where {
+    mzero = CodensityAsk (\q _ -> extract q);
+    mplus (CodensityAsk f) (CodensityAsk g) = CodensityAsk $ flip (\y -> flip f y =<= flip g y);
+  };
+
+  instance Applicative (CodensityAsk w) where {
+    pure = return;
+    (<*>) = ap;
+  };
+
+  instance Comonad w => Alternative (CodensityAsk w) where {
+    empty = CodensityAsk (\q _ -> extract q);
+    CodensityAsk f <|> CodensityAsk g = CodensityAsk $ flip (\y -> flip f y =<= flip g y);
+  };
+
+  instance Comonad w => Plus (CodensityAsk w) where {
+    zero = empty;
+    plus = (<|>);
+  };
+
+-- | Access the result of some 'CodensityAsk' by specifying an input which corresponds to the result.
+;
+  peekCodensityAsk :: w x -> CodensityAsk w x -> x;
+  peekCodensityAsk x (CodensityAsk f) = f x id;
+
+  peekCodensityAskT :: Applicative m => w (m x) -> CodensityAskT w m x -> m x;
+  peekCodensityAskT x (CodensityAskT f) = f x pure;
+
+  lowerCodensityAskT :: (Plus w, Applicative m) => CodensityAskT w m x -> m x;
+  lowerCodensityAskT (CodensityAskT f) = f zero pure;
+
+  catchCodensityAsk :: w (CodensityAsk w x) -> CodensityAsk w x -> CodensityAsk w x;
+  catchCodensityAsk w (CodensityAsk f) = f w return;
+
+  catchCodensityAskT :: (Functor w, Monad m) => w (CodensityAskT w m x) -> CodensityAskT w m x -> CodensityAskT w m x;
+  catchCodensityAskT w (CodensityAskT f) = join . lift $ f (return <$> w) (return . return);
+
+  data DensityAskT p f x = forall z. DensityAskT (p z -> f z -> x) (f z);
+
+-- | Density comonad taking a parameter holding something related to the output type. If this parameter is a 'Plus', you get a comonad.
+;
+  type DensityAsk p = DensityAskT p Identity;
+
+  instance Functor (DensityAskT p f) where {
+    fmap f (DensityAskT x y) = DensityAskT (\q -> f . x q) y;
+  };
+
+  instance Plus p => Extend (DensityAskT p f) where {
+    duplicate (DensityAskT x y) = DensityAskT (\q z -> DensityAskT (\q' z' -> x (plus q q') z') z) y;
+  };
+
+  instance Plus p => Comonad (DensityAskT p f) where {
+    extract (DensityAskT x y) = x zero y;
+  };
+
+  instance Plus p => ComonadTrans (DensityAskT p) where {
+    lower (DensityAskT x y) = y =>> x zero;
+  };
+
+  liftDensityAsk :: Comonad w => w x -> DensityAskT p w x;
+  liftDensityAsk = DensityAskT $ const extract;
+
+-- | Make a monad transformer from any comonad as Edward Kmett described.
+;
+  newtype CoT w m a = CoT { runCoT :: forall r. w (a -> m r) -> m r };
+
+  type Co w = CoT w Identity;
+
+  runCo :: Functor w => Co w a -> w (a -> r) -> r;
+  runCo m = runIdentity . runCoT m . fmap (fmap Identity);
+
+  instance Functor w => Functor (CoT w m) where {
+    fmap f (CoT w) = CoT (w . fmap (. f));
+  };
+
+  instance Comonad w => Applicative (CoT w m) where {
+    pure x = CoT (flip extract x);
+    f <*> x = f >>= flip fmap x;
+  };
+
+  instance Comonad w => Monad (CoT w m) where {
+    return x = CoT (flip extract x);
+    CoT k >>= f = CoT (k . extend (\w a -> runCoT (f a) w))
+  };
+
+  instance (Comonad w, Plus m) => Alternative (CoT w m) where {
+    empty = CoT (const zero);
+    CoT x <|> CoT y = CoT (liftA2 plus x y);
+  };
+
+  instance (Comonad w, Plus m) => MonadPlus (CoT w m) where {
+    mzero = CoT (const zero);
+    mplus (CoT x) (CoT y) = CoT (liftA2 plus x y);
+  };
+
+  instance Comonad w => MonadTrans (CoT w) where {
+    lift x = CoT (\z -> x >>= extract z);
+  };
+
+  liftCoT0 :: Comonad w => (forall a. w a -> s) -> CoT w m s;
+  liftCoT0 f = CoT (extract <*> f);
+
+  lowerCoT0 :: (Functor w, Applicative m) => CoT w m s -> w a -> m s;
+  lowerCoT0 (CoT m) = m . (pure <$);
+
+  lowerCo0 :: Functor w => Co w s -> w a -> s;
+  lowerCo0 (CoT m) = runIdentity . m . (return <$);
+
+  liftCoT1 :: (forall a. w a -> a) -> CoT w m ();
+  liftCoT1 f = CoT $ flip f ();
+
+  lowerCoT1 :: (Functor w, Applicative m) => CoT w m z -> w a -> m a;
+  lowerCoT1 (CoT m) = m . fmap (const . pure);
+
+  lowerCo1 :: Functor w => Co w z -> w a -> a;
+  lowerCo1 (CoT m) = runIdentity . m . fmap (const . return);
+
+-- | Finalize monad on '(->)' category. (The Finalize monad is the only possible monad of a endofunctor taking all objects to one final object of the category.)
+;
+  data Finalize x = Finalize;
+
+-- | Initialize comonad on '(->)' category. (The Initialize comonad is dual to the Finalize monad.)
+;
+  data Initialize x;
+
+  instance Functor Finalize where {
+    fmap _ Finalize = Finalize;
+  };
+
+  instance Contravariant Finalize where {
+    contramap _ Finalize = Finalize;
+  };
+
+  instance Applicative Finalize where {
+    pure _ = Finalize;
+    Finalize <*> Finalize = Finalize;
+  };
+
+  instance Monad Finalize where {
+    return _ = Finalize;
+    Finalize >>= _ = Finalize;
+  };
+
+  instance Alternative Finalize where {
+    empty = Finalize;
+    Finalize <|> Finalize = Finalize;
+  };
+
+  instance MonadPlus Finalize where {
+    mzero = Finalize;
+    mplus Finalize Finalize = Finalize;
+  };
+
+  instance Monoid (Finalize x) where {
+    mempty = Finalize;
+    mappend Finalize Finalize = Finalize;
+    mconcat _ = Finalize;
+  };
+
+  instance Functor Initialize where {
+    fmap _ _ = undefined;
+  };
+
+  instance Contravariant Initialize where {
+    contramap _ _ = undefined;
+  };
+
+  instance Extend Initialize where {
+    duplicate _ = undefined;
+  };
+
+  instance Comonad Initialize where {
+    extract _ = undefined;
+  };
+
+  data Decompose :: (* -> *) -> (* -> *) -> * -> * where {
+    Decompose :: y z -> Decompose x y (x z);
+  };
+
+  instance ComonadHoist (Decompose f) where {
+    cohoist (Decompose a) = Decompose (pure $ extract a);
+  };
+
+  data Recompose :: ((* -> *) -> (* -> *) -> * -> *) -> (* -> *) -> * -> * where {
+    Recompose :: forall (w :: (* -> *) -> (* -> *) -> * -> *) (x :: * -> *) y z. w x y (x z) -> Recompose w y z;
+  };
+
+-- instance Plus for other modules which Alternative
+
+  instance Plus [] where {
+    zero = [];
+    plus = (++);
+  };
+
+  instance Plus Maybe where {
+    zero = empty;
+    plus = (<|>);
+  };
+
+  instance Plus Seq where {
+    zero = mempty;
+    plus = mappend;
+  };
+
+  instance Ord k => Plus (Map k) where {
+    zero = mempty;
+    plus = mappend;
+  };
+
+  instance Plus IntMap where {
+    zero = mempty;
+    plus = mappend;
+  };
+
+  instance (Functor m, Monad m) => Plus (MaybeT m) where {
+    zero = empty;
+    plus = (<|>);
+  };
+
+  instance (ArrowZero a, ArrowPlus a) => Plus (WrappedArrow a b) where {
+    zero = empty;
+    plus = (<|>);
+  };
+
+  instance (Monoid w, Functor m, MonadPlus m) => Plus (RWST r w s m) where {
+    zero = mzero;
+    plus = mplus;
+  };
+
+  instance Plus f => Plus (ReaderT x f) where {
+    zero = ReaderT (const zero);
+    plus (ReaderT x) (ReaderT y) = ReaderT (liftA2 plus x y);
+  };
+
+  instance Plus f => Plus (WriterT x f) where {
+    zero = WriterT zero;
+    plus (WriterT x) (WriterT y) = WriterT (plus x y);
+  };
+
+  instance MonadPlus m => Plus (StateT s m) where {
+    zero = mzero;
+    plus = mplus;
+  };
+
+}
+
+-- Please notify me in case any of this is wrong. (I am not a mathematician.)
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple
+main = defaultMain
+ for-free.cabal view
@@ -0,0 +1,57 @@+-- for-free.cabal auto-generated by cabal init. For additional
+-- options, see
+-- http://www.haskell.org/cabal/release/cabal-latest/doc/users-guide/authors.html#pkg-descr.
+-- The name of the package.
+Name:                for-free
+
+-- The package version. See the Haskell package versioning policy
+-- (http://www.haskell.org/haskellwiki/Package_versioning_policy) for
+-- standards guiding when and how versions should be incremented.
+Version:             0.1
+
+-- A short (one-line) description of the package.
+Synopsis:            Functor, Monad, MonadPlus, etc for free
+
+-- A longer description of the package.
+Description:         Plus, OpT, Yoneda, CoYoneda, Free, Cofree, Density, Codensity, CoT, CodensityAsk, Initialize, Finalize, Decompose, Recompose
+
+-- The license under which the package is released.
+License:             PublicDomain
+
+-- The file containing the license text.
+-- License-file:        LICENSE
+
+-- The package author(s).
+-- Author:              
+
+-- An email address to which users can send suggestions, bug reports,
+-- and patches.
+-- Maintainer:          
+
+-- A copyright notice.
+-- Copyright:           
+
+Category:            Control
+
+Build-type:          Simple
+
+-- Extra files to be distributed with the package, such as examples or
+-- a README.
+-- Extra-source-files:  
+
+-- Constraint on the version of Cabal needed to build this package.
+Cabal-version:       >=1.6
+
+
+Library
+  -- Modules exported by the library.
+  Exposed-modules:     Control.ForFree
+  
+  -- Packages needed in order to build this package.
+  Build-depends:       base >= 4.3 && < 5, transformers >= 0.2.0.0 && < 0.4, containers >= 0.4.0.0 && < 0.5, contravariant >= 0.1.2 && < 0.3, comonad >= 1.1.0 && < 1.2, comonad-transformers >= 2.0.0 && < 2.2
+  
+  -- Modules not exported by this package.
+  -- Other-modules:       
+  
+  -- Extra tools (e.g. alex, hsc2hs, ...) needed to build the source.
+  -- Build-tools: