packages feed

comonad-coactions-0.1.0.0: src/Control/Comonad/TransformerStack.hs

{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeData #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UndecidableInstances #-}

module Control.Comonad.TransformerStack (ComonadTransStack (..)) where

import Control.Comonad.Coaction.TH
import Control.Comonad.Trans.Cofree ()
import Control.Comonad.Trans.Env ()
import Control.Comonad.Trans.Identity ()
import Control.Comonad.Trans.Store ()
import Control.Comonad.Trans.Traced ()

$mkLowerBy

-- | All @'ComonadTransStack'@ instances are defined inductively using @'Control.Comonad.Trans.Class.ComonadTrans'@ instances.
--
--   No laws are given in the documentation for @'Control.Comonad.Trans.Class.ComonadTrans'@,
--   but all instances should satisfy the following laws, dual to the laws for
--   @'Control.Monad.Trans.Class.MonadTrans'@, which state that @'Control.Comonad.Trans.Class.lower'@ is a comonad homomorphism:
--
--   * @'Control.Comonad.extract' '.' 'Control.Comonad.Trans.Class.lower' = 'Control.Comonad.extract'@
--
--   * @'Control.Comonad.duplicate' '.' 'Control.Comonad.Trans.Class.lower' = 'Control.Comonad.Trans.Class.lower' '.' 'fmap' 'Control.Comonad.Trans.Class.lower' . 'Control.Comonad.duplicate'@
--
--   It follows by induction that @'lowerStack'@ is a comonad homomorphism.
--   The proofs of the comodule laws may be obtained by looking at the corresponding
--   proofs of the module laws in a mirror.
class (LowerBy (Steps w q) w q) => ComonadTransStack w q where
  lowerStack :: forall a. q a -> w a

instance (LowerBy (Steps w q) w q) => ComonadTransStack w q where
  lowerStack = lowerBy @(Steps w q)