    {-# LANGUAGE
      RankNTypes,
      FlexibleInstances,
      FlexibleContexts,
      MultiParamTypeClasses,
      UndecidableInstances,
      FunctionalDependencies #-}

    -- Suppress warnings about ''Control.Monad.Error'' being deprecated.

    {-# OPTIONS_GHC -fno-warn-deprecations #-}

    --------------------------------------------------------------------------------
    -- |
    -- Module      : Data.Equivalence.Monad
    -- Copyright   : Patrick Bahr, 2010
    -- License     : All Rights Reserved
    --
    -- Maintainer  :  Patrick Bahr
    -- Stability   :  unknown
    -- Portability :  unknown
    --
    -- This is an alternative interface to the union-find implementation
    -- in ''Data.Equivalence.STT''. It is wrapped into the monad
    -- transformer 'EquivT'.
    --
    --------------------------------------------------------------------------------

    module Data.Equivalence.Monad
        (
         MonadEquiv(..),
         EquivT(..),
         EquivT',
         EquivM,
         EquivM',
         runEquivT,
         runEquivT',
         runEquivM,
         runEquivM'
         ) where

    import Data.Equivalence.STT hiding (equate, equateAll, equivalent, classDesc, removeClass,
                                        getClass , combine, combineAll, same , desc , remove )
    import qualified Data.Equivalence.STT  as S

    import Control.Monad.Writer
    import Control.Monad.Reader
    import Control.Monad.Error.Class
    import Control.Monad.State
    import Control.Monad.Trans
    import Control.Monad.Identity
    import Control.Monad.ST.Trans
    import Control.Monad.Trans.Error (ErrorT)
    import Control.Monad.Trans.Except (ExceptT)
    import Control.Applicative
    import qualified Control.Monad.Fail as Fail

    {-| This monad transformer encapsulates computations maintaining an
    equivalence relation. A monadic computation of type 'EquivT' @s c v m
    a@ maintains a state space indexed by type @s@, maintains an
    equivalence relation over elements of type @v@ with equivalence class
    descriptors of type @c@ and contains an internal monadic computation
    of type @m a@. -}

    newtype EquivT s c v m a = EquivT {EquivT s c v m a -> ReaderT (Equiv s c v) (STT s m) a
    unEquivT :: ReaderT (Equiv s c v) (STT s m) a}

    {-| This monad transformer is a special case of 'EquivT' that only
    maintains trivial equivalence class descriptors of type @()@. -}

    type EquivT' s = EquivT s ()

    {-| This monad encapsulates computations maintaining an equivalence
    relation. A monadic computation of type 'EquivM' @s c v a@ maintains a
    state space indexed by type @s@, maintains an equivalence relation
    over elements of type @v@ with equivalence class descriptors of type
    @c@ and returns a value of type @a@.  -}

    type EquivM s c v = EquivT s c v Identity

    {-| This monad is a special case of 'EquivM' that only maintains
    trivial equivalence class descriptors of type @()@. -}

    type EquivM' s v = EquivM s () v

    instance Functor m => Functor (EquivT s c v m) where
      fmap :: (a -> b) -> EquivT s c v m a -> EquivT s c v m b
    fmap f :: a -> b
    f (EquivT m :: ReaderT (Equiv s c v) (STT s m) a
    m) = ReaderT (Equiv s c v) (STT s m) b -> EquivT s c v m b
    forall s c v (m :: * -> *) a.
    ReaderT (Equiv s c v) (STT s m) a -> EquivT s c v m a
    EquivT (ReaderT (Equiv s c v) (STT s m) b -> EquivT s c v m b)
    -> ReaderT (Equiv s c v) (STT s m) b -> EquivT s c v m b
    forall a b. (a -> b) -> a -> b
    $ (a -> b)
    -> ReaderT (Equiv s c v) (STT s m) a
    -> ReaderT (Equiv s c v) (STT s m) b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap a -> b
    f ReaderT (Equiv s c v) (STT s m) a
    m

    instance (Applicative m, Monad m) => Applicative (EquivT s c v m) where
      pure :: a -> EquivT s c v m a
    pure = ReaderT (Equiv s c v) (STT s m) a -> EquivT s c v m a
    forall s c v (m :: * -> *) a.
    ReaderT (Equiv s c v) (STT s m) a -> EquivT s c v m a
    EquivT (ReaderT (Equiv s c v) (STT s m) a -> EquivT s c v m a)
    -> (a -> ReaderT (Equiv s c v) (STT s m) a)
    -> a
    -> EquivT s c v m a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . a -> ReaderT (Equiv s c v) (STT s m) a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure
      (EquivT f :: ReaderT (Equiv s c v) (STT s m) (a -> b)
    f) <*> :: EquivT s c v m (a -> b) -> EquivT s c v m a -> EquivT s c v m b
    <*> (EquivT a :: ReaderT (Equiv s c v) (STT s m) a
    a) = ReaderT (Equiv s c v) (STT s m) b -> EquivT s c v m b
    forall s c v (m :: * -> *) a.
    ReaderT (Equiv s c v) (STT s m) a -> EquivT s c v m a
    EquivT (ReaderT (Equiv s c v) (STT s m) (a -> b)
    f ReaderT (Equiv s c v) (STT s m) (a -> b)
    -> ReaderT (Equiv s c v) (STT s m) a
    -> ReaderT (Equiv s c v) (STT s m) b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> ReaderT (Equiv s c v) (STT s m) a
    a)

    instance (Monad m) => Monad (EquivT s c v m) where
        EquivT m :: ReaderT (Equiv s c v) (STT s m) a
    m >>= :: EquivT s c v m a -> (a -> EquivT s c v m b) -> EquivT s c v m b
    >>= f :: a -> EquivT s c v m b
    f = ReaderT (Equiv s c v) (STT s m) b -> EquivT s c v m b
    forall s c v (m :: * -> *) a.
    ReaderT (Equiv s c v) (STT s m) a -> EquivT s c v m a
    EquivT (ReaderT (Equiv s c v) (STT s m) a
    m ReaderT (Equiv s c v) (STT s m) a
    -> (a -> ReaderT (Equiv s c v) (STT s m) b)
    -> ReaderT (Equiv s c v) (STT s m) b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= (EquivT s c v m b -> ReaderT (Equiv s c v) (STT s m) b
    forall s c v (m :: * -> *) a.
    EquivT s c v m a -> ReaderT (Equiv s c v) (STT s m) a
    unEquivT (EquivT s c v m b -> ReaderT (Equiv s c v) (STT s m) b)
    -> (a -> EquivT s c v m b)
    -> a
    -> ReaderT (Equiv s c v) (STT s m) b
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . a -> EquivT s c v m b
    f))
        return :: a -> EquivT s c v m a
    return = ReaderT (Equiv s c v) (STT s m) a -> EquivT s c v m a
    forall s c v (m :: * -> *) a.
    ReaderT (Equiv s c v) (STT s m) a -> EquivT s c v m a
    EquivT (ReaderT (Equiv s c v) (STT s m) a -> EquivT s c v m a)
    -> (a -> ReaderT (Equiv s c v) (STT s m) a)
    -> a
    -> EquivT s c v m a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . a -> ReaderT (Equiv s c v) (STT s m) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return

    instance MonadTrans (EquivT s c v) where
        lift :: m a -> EquivT s c v m a
    lift = ReaderT (Equiv s c v) (STT s m) a -> EquivT s c v m a
    forall s c v (m :: * -> *) a.
    ReaderT (Equiv s c v) (STT s m) a -> EquivT s c v m a
    EquivT (ReaderT (Equiv s c v) (STT s m) a -> EquivT s c v m a)
    -> (m a -> ReaderT (Equiv s c v) (STT s m) a)
    -> m a
    -> EquivT s c v m a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . STT s m a -> ReaderT (Equiv s c v) (STT s m) a
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (STT s m a -> ReaderT (Equiv s c v) (STT s m) a)
    -> (m a -> STT s m a) -> m a -> ReaderT (Equiv s c v) (STT s m) a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . m a -> STT s m a
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift

    instance Monad m => Fail.MonadFail (EquivT s c v m) where
        fail :: String -> EquivT s c v m a
    fail = String -> EquivT s c v m a
    forall a. HasCallStack => String -> a
    error

    instance (MonadReader r m) => MonadReader r (EquivT s c v m) where
        ask :: EquivT s c v m r
    ask = ReaderT (Equiv s c v) (STT s m) r -> EquivT s c v m r
    forall s c v (m :: * -> *) a.
    ReaderT (Equiv s c v) (STT s m) a -> EquivT s c v m a
    EquivT (ReaderT (Equiv s c v) (STT s m) r -> EquivT s c v m r)
    -> ReaderT (Equiv s c v) (STT s m) r -> EquivT s c v m r
    forall a b. (a -> b) -> a -> b
    $ STT s m r -> ReaderT (Equiv s c v) (STT s m) r
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift STT s m r
    forall r (m :: * -> *). MonadReader r m => m r
    ask
        local :: (r -> r) -> EquivT s c v m a -> EquivT s c v m a
    local f :: r -> r
    f (EquivT (ReaderT m :: Equiv s c v -> STT s m a
    m)) = ReaderT (Equiv s c v) (STT s m) a -> EquivT s c v m a
    forall s c v (m :: * -> *) a.
    ReaderT (Equiv s c v) (STT s m) a -> EquivT s c v m a
    EquivT (ReaderT (Equiv s c v) (STT s m) a -> EquivT s c v m a)
    -> ReaderT (Equiv s c v) (STT s m) a -> EquivT s c v m a
    forall a b. (a -> b) -> a -> b
    $ (Equiv s c v -> STT s m a) -> ReaderT (Equiv s c v) (STT s m) a
    forall r (m :: * -> *) a. (r -> m a) -> ReaderT r m a
    ReaderT ((Equiv s c v -> STT s m a) -> ReaderT (Equiv s c v) (STT s m) a)
    -> (Equiv s c v -> STT s m a) -> ReaderT (Equiv s c v) (STT s m) a
    forall a b. (a -> b) -> a -> b
    $ (\ r :: Equiv s c v
    r -> (r -> r) -> STT s m a -> STT s m a
    forall r (m :: * -> *) a. MonadReader r m => (r -> r) -> m a -> m a
    local r -> r
    f (Equiv s c v -> STT s m a
    m Equiv s c v
    r))

    instance (Monoid w, MonadWriter w m) => MonadWriter w (EquivT s c v m) where
        tell :: w -> EquivT s c v m ()
    tell w :: w
    w = ReaderT (Equiv s c v) (STT s m) () -> EquivT s c v m ()
    forall s c v (m :: * -> *) a.
    ReaderT (Equiv s c v) (STT s m) a -> EquivT s c v m a
    EquivT (ReaderT (Equiv s c v) (STT s m) () -> EquivT s c v m ())
    -> ReaderT (Equiv s c v) (STT s m) () -> EquivT s c v m ()
    forall a b. (a -> b) -> a -> b
    $ w -> ReaderT (Equiv s c v) (STT s m) ()
    forall w (m :: * -> *). MonadWriter w m => w -> m ()
    tell w
    w
        listen :: EquivT s c v m a -> EquivT s c v m (a, w)
    listen (EquivT m :: ReaderT (Equiv s c v) (STT s m) a
    m) = ReaderT (Equiv s c v) (STT s m) (a, w) -> EquivT s c v m (a, w)
    forall s c v (m :: * -> *) a.
    ReaderT (Equiv s c v) (STT s m) a -> EquivT s c v m a
    EquivT (ReaderT (Equiv s c v) (STT s m) (a, w) -> EquivT s c v m (a, w))
    -> ReaderT (Equiv s c v) (STT s m) (a, w) -> EquivT s c v m (a, w)
    forall a b. (a -> b) -> a -> b
    $ ReaderT (Equiv s c v) (STT s m) a
    -> ReaderT (Equiv s c v) (STT s m) (a, w)
    forall w (m :: * -> *) a. MonadWriter w m => m a -> m (a, w)
    listen ReaderT (Equiv s c v) (STT s m) a
    m
        pass :: EquivT s c v m (a, w -> w) -> EquivT s c v m a
    pass (EquivT m :: ReaderT (Equiv s c v) (STT s m) (a, w -> w)
    m) = ReaderT (Equiv s c v) (STT s m) a -> EquivT s c v m a
    forall s c v (m :: * -> *) a.
    ReaderT (Equiv s c v) (STT s m) a -> EquivT s c v m a
    EquivT (ReaderT (Equiv s c v) (STT s m) a -> EquivT s c v m a)
    -> ReaderT (Equiv s c v) (STT s m) a -> EquivT s c v m a
    forall a b. (a -> b) -> a -> b
    $ ReaderT (Equiv s c v) (STT s m) (a, w -> w)
    -> ReaderT (Equiv s c v) (STT s m) a
    forall w (m :: * -> *) a. MonadWriter w m => m (a, w -> w) -> m a
    pass ReaderT (Equiv s c v) (STT s m) (a, w -> w)
    m

    instance (MonadState st m) => MonadState st (EquivT s c v m) where
        get :: EquivT s c v m st
    get = ReaderT (Equiv s c v) (STT s m) st -> EquivT s c v m st
    forall s c v (m :: * -> *) a.
    ReaderT (Equiv s c v) (STT s m) a -> EquivT s c v m a
    EquivT ReaderT (Equiv s c v) (STT s m) st
    forall s (m :: * -> *). MonadState s m => m s
    get
        put :: st -> EquivT s c v m ()
    put s :: st
    s = ReaderT (Equiv s c v) (STT s m) () -> EquivT s c v m ()
    forall s c v (m :: * -> *) a.
    ReaderT (Equiv s c v) (STT s m) a -> EquivT s c v m a
    EquivT (ReaderT (Equiv s c v) (STT s m) () -> EquivT s c v m ())
    -> ReaderT (Equiv s c v) (STT s m) () -> EquivT s c v m ()
    forall a b. (a -> b) -> a -> b
    $ st -> ReaderT (Equiv s c v) (STT s m) ()
    forall s (m :: * -> *). MonadState s m => s -> m ()
    put st
    s

    instance (MonadError e m) => MonadError e (EquivT s c v m) where
        throwError :: e -> EquivT s c v m a
    throwError e :: e
    e = m a -> EquivT s c v m a
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (m a -> EquivT s c v m a) -> m a -> EquivT s c v m a
    forall a b. (a -> b) -> a -> b
    $ e -> m a
    forall e (m :: * -> *) a. MonadError e m => e -> m a
    throwError e
    e
        catchError :: EquivT s c v m a -> (e -> EquivT s c v m a) -> EquivT s c v m a
    catchError (EquivT m :: ReaderT (Equiv s c v) (STT s m) a
    m) f :: e -> EquivT s c v m a
    f = ReaderT (Equiv s c v) (STT s m) a -> EquivT s c v m a
    forall s c v (m :: * -> *) a.
    ReaderT (Equiv s c v) (STT s m) a -> EquivT s c v m a
    EquivT (ReaderT (Equiv s c v) (STT s m) a -> EquivT s c v m a)
    -> ReaderT (Equiv s c v) (STT s m) a -> EquivT s c v m a
    forall a b. (a -> b) -> a -> b
    $ ReaderT (Equiv s c v) (STT s m) a
    -> (e -> ReaderT (Equiv s c v) (STT s m) a)
    -> ReaderT (Equiv s c v) (STT s m) a
    forall e (m :: * -> *) a.
    MonadError e m =>
    m a -> (e -> m a) -> m a
    catchError ReaderT (Equiv s c v) (STT s m) a
    m (EquivT s c v m a -> ReaderT (Equiv s c v) (STT s m) a
    forall s c v (m :: * -> *) a.
    EquivT s c v m a -> ReaderT (Equiv s c v) (STT s m) a
    unEquivT (EquivT s c v m a -> ReaderT (Equiv s c v) (STT s m) a)
    -> (e -> EquivT s c v m a)
    -> e
    -> ReaderT (Equiv s c v) (STT s m) a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . e -> EquivT s c v m a
    f)

    {-| This function runs a monadic computation that maintains an
    equivalence relation. The first tow arguments specify how to construct
    an equivalence class descriptor for a singleton class and how to
    combine two equivalence class descriptors. -}

    runEquivT :: (Monad m, Applicative m)
              => (v -> c) -- ^ used to construct an equivalence class descriptor for a singleton class
              -> (c -> c -> c) -- ^ used to combine the equivalence class descriptor of two classes
                               --   which are meant to be combined.
              -> (forall s. EquivT s c v m a)
              -> m a
    runEquivT :: (v -> c) -> (c -> c -> c) -> (forall s. EquivT s c v m a) -> m a
    runEquivT mk :: v -> c
    mk com :: c -> c -> c
    com m :: forall s. EquivT s c v m a
    m = (forall s. STT s m a) -> m a
    forall (m :: * -> *) a. Monad m => (forall s. STT s m a) -> m a
    runST ((forall s. STT s m a) -> m a) -> (forall s. STT s m a) -> m a
    forall a b. (a -> b) -> a -> b
    $ do
      Equiv s c v
    p <- (v -> c) -> (c -> c -> c) -> STT s m (Equiv s c v)
    forall (m :: * -> *) a c s.
    (Monad m, Applicative m) =>
    (a -> c) -> (c -> c -> c) -> STT s m (Equiv s c a)
    leastEquiv v -> c
    mk c -> c -> c
    com
      (ReaderT (Equiv s c v) (STT s m) a -> Equiv s c v -> STT s m a
    forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
    `runReaderT` Equiv s c v
    p) (ReaderT (Equiv s c v) (STT s m) a -> STT s m a)
    -> ReaderT (Equiv s c v) (STT s m) a -> STT s m a
    forall a b. (a -> b) -> a -> b
    $ EquivT s c v m a -> ReaderT (Equiv s c v) (STT s m) a
    forall s c v (m :: * -> *) a.
    EquivT s c v m a -> ReaderT (Equiv s c v) (STT s m) a
    unEquivT EquivT s c v m a
    forall s. EquivT s c v m a
    m

    {-| This function is a special case of 'runEquivT' that only maintains
    trivial equivalence class descriptors of type @()@. -}

    runEquivT' :: (Monad m, Applicative m) => (forall s. EquivT' s v m a) -> m a
    runEquivT' :: (forall s. EquivT' s v m a) -> m a
    runEquivT' = (v -> ()) -> (() -> () -> ()) -> (forall s. EquivT' s v m a) -> m a
    forall (m :: * -> *) v c a.
    (Monad m, Applicative m) =>
    (v -> c) -> (c -> c -> c) -> (forall s. EquivT s c v m a) -> m a
    runEquivT (() -> v -> ()
    forall a b. a -> b -> a
    const ()) (\_ _-> ())

    {-| This function runs a monadic computation that maintains an
    equivalence relation. The first tow arguments specify how to construct
    an equivalence class descriptor for a singleton class and how to
    combine two equivalence class descriptors. -}
    runEquivM :: (v -> c) -- ^ used to construct an equivalence class descriptor for a singleton class
              -> (c -> c -> c) -- ^ used to combine the equivalence class descriptor of two classes
                               --   which are meant to be combined.
              -> (forall s. EquivM s c v a)
              -> a
    runEquivM :: (v -> c) -> (c -> c -> c) -> (forall s. EquivM s c v a) -> a
    runEquivM sing :: v -> c
    sing comb :: c -> c -> c
    comb m :: forall s. EquivM s c v a
    m = Identity a -> a
    forall a. Identity a -> a
    runIdentity (Identity a -> a) -> Identity a -> a
    forall a b. (a -> b) -> a -> b
    $ (v -> c)
    -> (c -> c -> c) -> (forall s. EquivM s c v a) -> Identity a
    forall (m :: * -> *) v c a.
    (Monad m, Applicative m) =>
    (v -> c) -> (c -> c -> c) -> (forall s. EquivT s c v m a) -> m a
    runEquivT v -> c
    sing c -> c -> c
    comb forall s. EquivM s c v a
    m

    {-| This function is a special case of 'runEquivM' that only maintains
    trivial equivalence class descriptors of type @()@. -}

    runEquivM' :: (forall s. EquivM' s v a) -> a
    runEquivM' :: (forall s. EquivM' s v a) -> a
    runEquivM' = (v -> ()) -> (() -> () -> ()) -> (forall s. EquivM' s v a) -> a
    forall v c a.
    (v -> c) -> (c -> c -> c) -> (forall s. EquivM s c v a) -> a
    runEquivM (() -> v -> ()
    forall a b. a -> b -> a
    const ()) (\_ _ -> ())

    {-| This class specifies the interface for a monadic computation that
    maintains an equivalence relation.  -}

    class (Monad m, Applicative m, Ord v) => MonadEquiv c v d m | m -> v, m -> c, m -> d where
        {-| This function decides whether the two given elements are
            equivalent in the current equivalence relation -}

        equivalent :: v -> v -> m Bool
        {-| This function obtains the descriptor of the given element's
            equivalence class. -}

        classDesc :: v -> m d

        {-| This function equates the element in the given list. That is, it
          unions the equivalence classes of the elements and combines their
          descriptor. -}

        equateAll :: [v] -> m ()

        {-| This function equates the given two elements. That is it
            unions the equivalence classes of the two elements. -}

        equate :: v -> v -> m ()
        equate x :: v
    x y :: v
    y = [v] -> m ()
    forall c v d (m :: * -> *). MonadEquiv c v d m => [v] -> m ()
    equateAll [v
    x,v
    y]

        {-| This function removes the equivalence class of the given
          element. If there is no corresponding equivalence class, @False@ is
          returned; otherwise @True@. -}
        removeClass :: v -> m Bool

        {-| This function provides the equivalence class the given element
          is contained in. -}

        getClass :: v -> m c

        {-| This function combines all equivalence classes in the given
          list. Afterwards all elements in the argument list represent the same
          equivalence class! -}

        combineAll :: [c] -> m ()

        {-| This function combines the two given equivalence
          classes. Afterwards both arguments represent the same equivalence
          class! One of it is returned in order to represent the new combined
          equivalence class. -}

        combine :: c -> c -> m c
        combine x :: c
    x y :: c
    y = [c] -> m ()
    forall c v d (m :: * -> *). MonadEquiv c v d m => [c] -> m ()
    combineAll [c
    x,c
    y] m () -> m c -> m c
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> c -> m c
    forall (m :: * -> *) a. Monad m => a -> m a
    return c
    x

        {-| This function decides whether the two given equivalence classes
          are the same. -}

        (===) :: c -> c -> m Bool

        {-| This function returns the descriptor of the given
          equivalence class. -}

        desc :: c -> m d

        {-| This function removes the given equivalence class. If the
          equivalence class does not exists anymore @False@ is returned;
          otherwise @True@. -}

        remove :: c -> m Bool

    instance (Monad m, Applicative m, Ord v) => MonadEquiv (Class s d v) v d (EquivT s d v m) where
        equivalent :: v -> v -> EquivT s d v m Bool
    equivalent x :: v
    x y :: v
    y = ReaderT (Equiv s d v) (STT s m) Bool -> EquivT s d v m Bool
    forall s c v (m :: * -> *) a.
    ReaderT (Equiv s c v) (STT s m) a -> EquivT s c v m a
    EquivT (ReaderT (Equiv s d v) (STT s m) Bool -> EquivT s d v m Bool)
    -> ReaderT (Equiv s d v) (STT s m) Bool -> EquivT s d v m Bool
    forall a b. (a -> b) -> a -> b
    $ do
          Equiv s d v
    part <- ReaderT (Equiv s d v) (STT s m) (Equiv s d v)
    forall r (m :: * -> *). MonadReader r m => m r
    ask
          STT s m Bool -> ReaderT (Equiv s d v) (STT s m) Bool
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (STT s m Bool -> ReaderT (Equiv s d v) (STT s m) Bool)
    -> STT s m Bool -> ReaderT (Equiv s d v) (STT s m) Bool
    forall a b. (a -> b) -> a -> b
    $ Equiv s d v -> v -> v -> STT s m Bool
    forall (m :: * -> *) a s c.
    (Monad m, Applicative m, Ord a) =>
    Equiv s c a -> a -> a -> STT s m Bool
    S.equivalent Equiv s d v
    part v
    x v
    y

        classDesc :: v -> EquivT s d v m d
    classDesc x :: v
    x = ReaderT (Equiv s d v) (STT s m) d -> EquivT s d v m d
    forall s c v (m :: * -> *) a.
    ReaderT (Equiv s c v) (STT s m) a -> EquivT s c v m a
    EquivT (ReaderT (Equiv s d v) (STT s m) d -> EquivT s d v m d)
    -> ReaderT (Equiv s d v) (STT s m) d -> EquivT s d v m d
    forall a b. (a -> b) -> a -> b
    $ do
          Equiv s d v
    part <- ReaderT (Equiv s d v) (STT s m) (Equiv s d v)
    forall r (m :: * -> *). MonadReader r m => m r
    ask
          STT s m d -> ReaderT (Equiv s d v) (STT s m) d
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (STT s m d -> ReaderT (Equiv s d v) (STT s m) d)
    -> STT s m d -> ReaderT (Equiv s d v) (STT s m) d
    forall a b. (a -> b) -> a -> b
    $ Equiv s d v -> v -> STT s m d
    forall (m :: * -> *) a s c.
    (Monad m, Applicative m, Ord a) =>
    Equiv s c a -> a -> STT s m c
    S.classDesc Equiv s d v
    part v
    x

        equateAll :: [v] -> EquivT s d v m ()
    equateAll x :: [v]
    x = ReaderT (Equiv s d v) (STT s m) () -> EquivT s d v m ()
    forall s c v (m :: * -> *) a.
    ReaderT (Equiv s c v) (STT s m) a -> EquivT s c v m a
    EquivT (ReaderT (Equiv s d v) (STT s m) () -> EquivT s d v m ())
    -> ReaderT (Equiv s d v) (STT s m) () -> EquivT s d v m ()
    forall a b. (a -> b) -> a -> b
    $ do
          Equiv s d v
    part <- ReaderT (Equiv s d v) (STT s m) (Equiv s d v)
    forall r (m :: * -> *). MonadReader r m => m r
    ask
          STT s m () -> ReaderT (Equiv s d v) (STT s m) ()
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (STT s m () -> ReaderT (Equiv s d v) (STT s m) ())
    -> STT s m () -> ReaderT (Equiv s d v) (STT s m) ()
    forall a b. (a -> b) -> a -> b
    $ Equiv s d v -> [v] -> STT s m ()
    forall (m :: * -> *) a s c.
    (Monad m, Applicative m, Ord a) =>
    Equiv s c a -> [a] -> STT s m ()
    S.equateAll Equiv s d v
    part [v]
    x

        equate :: v -> v -> EquivT s d v m ()
    equate x :: v
    x y :: v
    y = ReaderT (Equiv s d v) (STT s m) () -> EquivT s d v m ()
    forall s c v (m :: * -> *) a.
    ReaderT (Equiv s c v) (STT s m) a -> EquivT s c v m a
    EquivT (ReaderT (Equiv s d v) (STT s m) () -> EquivT s d v m ())
    -> ReaderT (Equiv s d v) (STT s m) () -> EquivT s d v m ()
    forall a b. (a -> b) -> a -> b
    $ do
          Equiv s d v
    part <- ReaderT (Equiv s d v) (STT s m) (Equiv s d v)
    forall r (m :: * -> *). MonadReader r m => m r
    ask
          STT s m () -> ReaderT (Equiv s d v) (STT s m) ()
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (STT s m () -> ReaderT (Equiv s d v) (STT s m) ())
    -> STT s m () -> ReaderT (Equiv s d v) (STT s m) ()
    forall a b. (a -> b) -> a -> b
    $ Equiv s d v -> v -> v -> STT s m ()
    forall (m :: * -> *) a s c.
    (Monad m, Applicative m, Ord a) =>
    Equiv s c a -> a -> a -> STT s m ()
    S.equate Equiv s d v
    part v
    x v
    y

        removeClass :: v -> EquivT s d v m Bool
    removeClass x :: v
    x = ReaderT (Equiv s d v) (STT s m) Bool -> EquivT s d v m Bool
    forall s c v (m :: * -> *) a.
    ReaderT (Equiv s c v) (STT s m) a -> EquivT s c v m a
    EquivT (ReaderT (Equiv s d v) (STT s m) Bool -> EquivT s d v m Bool)
    -> ReaderT (Equiv s d v) (STT s m) Bool -> EquivT s d v m Bool
    forall a b. (a -> b) -> a -> b
    $ do
          Equiv s d v
    part <- ReaderT (Equiv s d v) (STT s m) (Equiv s d v)
    forall r (m :: * -> *). MonadReader r m => m r
    ask
          STT s m Bool -> ReaderT (Equiv s d v) (STT s m) Bool
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (STT s m Bool -> ReaderT (Equiv s d v) (STT s m) Bool)
    -> STT s m Bool -> ReaderT (Equiv s d v) (STT s m) Bool
    forall a b. (a -> b) -> a -> b
    $ Equiv s d v -> v -> STT s m Bool
    forall (m :: * -> *) a s c.
    (Monad m, Applicative m, Ord a) =>
    Equiv s c a -> a -> STT s m Bool
    S.removeClass Equiv s d v
    part v
    x

        getClass :: v -> EquivT s d v m (Class s d v)
    getClass x :: v
    x = ReaderT (Equiv s d v) (STT s m) (Class s d v)
    -> EquivT s d v m (Class s d v)
    forall s c v (m :: * -> *) a.
    ReaderT (Equiv s c v) (STT s m) a -> EquivT s c v m a
    EquivT (ReaderT (Equiv s d v) (STT s m) (Class s d v)
     -> EquivT s d v m (Class s d v))
    -> ReaderT (Equiv s d v) (STT s m) (Class s d v)
    -> EquivT s d v m (Class s d v)
    forall a b. (a -> b) -> a -> b
    $ do
          Equiv s d v
    part <- ReaderT (Equiv s d v) (STT s m) (Equiv s d v)
    forall r (m :: * -> *). MonadReader r m => m r
    ask
          STT s m (Class s d v)
    -> ReaderT (Equiv s d v) (STT s m) (Class s d v)
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (STT s m (Class s d v)
     -> ReaderT (Equiv s d v) (STT s m) (Class s d v))
    -> STT s m (Class s d v)
    -> ReaderT (Equiv s d v) (STT s m) (Class s d v)
    forall a b. (a -> b) -> a -> b
    $ Equiv s d v -> v -> STT s m (Class s d v)
    forall (m :: * -> *) a s c.
    (Monad m, Applicative m, Ord a) =>
    Equiv s c a -> a -> STT s m (Class s c a)
    S.getClass Equiv s d v
    part v
    x

        combineAll :: [Class s d v] -> EquivT s d v m ()
    combineAll x :: [Class s d v]
    x = ReaderT (Equiv s d v) (STT s m) () -> EquivT s d v m ()
    forall s c v (m :: * -> *) a.
    ReaderT (Equiv s c v) (STT s m) a -> EquivT s c v m a
    EquivT (ReaderT (Equiv s d v) (STT s m) () -> EquivT s d v m ())
    -> ReaderT (Equiv s d v) (STT s m) () -> EquivT s d v m ()
    forall a b. (a -> b) -> a -> b
    $ do
          Equiv s d v
    part <- ReaderT (Equiv s d v) (STT s m) (Equiv s d v)
    forall r (m :: * -> *). MonadReader r m => m r
    ask
          STT s m () -> ReaderT (Equiv s d v) (STT s m) ()
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (STT s m () -> ReaderT (Equiv s d v) (STT s m) ())
    -> STT s m () -> ReaderT (Equiv s d v) (STT s m) ()
    forall a b. (a -> b) -> a -> b
    $ Equiv s d v -> [Class s d v] -> STT s m ()
    forall (m :: * -> *) a s c.
    (Monad m, Applicative m, Ord a) =>
    Equiv s c a -> [Class s c a] -> STT s m ()
    S.combineAll Equiv s d v
    part [Class s d v]
    x

        combine :: Class s d v -> Class s d v -> EquivT s d v m (Class s d v)
    combine x :: Class s d v
    x y :: Class s d v
    y = ReaderT (Equiv s d v) (STT s m) (Class s d v)
    -> EquivT s d v m (Class s d v)
    forall s c v (m :: * -> *) a.
    ReaderT (Equiv s c v) (STT s m) a -> EquivT s c v m a
    EquivT (ReaderT (Equiv s d v) (STT s m) (Class s d v)
     -> EquivT s d v m (Class s d v))
    -> ReaderT (Equiv s d v) (STT s m) (Class s d v)
    -> EquivT s d v m (Class s d v)
    forall a b. (a -> b) -> a -> b
    $ do
          Equiv s d v
    part <- ReaderT (Equiv s d v) (STT s m) (Equiv s d v)
    forall r (m :: * -> *). MonadReader r m => m r
    ask
          STT s m (Class s d v)
    -> ReaderT (Equiv s d v) (STT s m) (Class s d v)
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (STT s m (Class s d v)
     -> ReaderT (Equiv s d v) (STT s m) (Class s d v))
    -> STT s m (Class s d v)
    -> ReaderT (Equiv s d v) (STT s m) (Class s d v)
    forall a b. (a -> b) -> a -> b
    $ Equiv s d v -> Class s d v -> Class s d v -> STT s m (Class s d v)
    forall (m :: * -> *) a s c.
    (Monad m, Applicative m, Ord a) =>
    Equiv s c a -> Class s c a -> Class s c a -> STT s m (Class s c a)
    S.combine Equiv s d v
    part Class s d v
    x Class s d v
    y

        x :: Class s d v
    x === :: Class s d v -> Class s d v -> EquivT s d v m Bool
    === y :: Class s d v
    y = ReaderT (Equiv s d v) (STT s m) Bool -> EquivT s d v m Bool
    forall s c v (m :: * -> *) a.
    ReaderT (Equiv s c v) (STT s m) a -> EquivT s c v m a
    EquivT (ReaderT (Equiv s d v) (STT s m) Bool -> EquivT s d v m Bool)
    -> ReaderT (Equiv s d v) (STT s m) Bool -> EquivT s d v m Bool
    forall a b. (a -> b) -> a -> b
    $ do
          Equiv s d v
    part <- ReaderT (Equiv s d v) (STT s m) (Equiv s d v)
    forall r (m :: * -> *). MonadReader r m => m r
    ask
          STT s m Bool -> ReaderT (Equiv s d v) (STT s m) Bool
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (STT s m Bool -> ReaderT (Equiv s d v) (STT s m) Bool)
    -> STT s m Bool -> ReaderT (Equiv s d v) (STT s m) Bool
    forall a b. (a -> b) -> a -> b
    $ Equiv s d v -> Class s d v -> Class s d v -> STT s m Bool
    forall (m :: * -> *) a s c.
    (Monad m, Applicative m, Ord a) =>
    Equiv s c a -> Class s c a -> Class s c a -> STT s m Bool
    S.same Equiv s d v
    part Class s d v
    x Class s d v
    y

        desc :: Class s d v -> EquivT s d v m d
    desc x :: Class s d v
    x = ReaderT (Equiv s d v) (STT s m) d -> EquivT s d v m d
    forall s c v (m :: * -> *) a.
    ReaderT (Equiv s c v) (STT s m) a -> EquivT s c v m a
    EquivT (ReaderT (Equiv s d v) (STT s m) d -> EquivT s d v m d)
    -> ReaderT (Equiv s d v) (STT s m) d -> EquivT s d v m d
    forall a b. (a -> b) -> a -> b
    $ do
          Equiv s d v
    part <- ReaderT (Equiv s d v) (STT s m) (Equiv s d v)
    forall r (m :: * -> *). MonadReader r m => m r
    ask
          STT s m d -> ReaderT (Equiv s d v) (STT s m) d
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (STT s m d -> ReaderT (Equiv s d v) (STT s m) d)
    -> STT s m d -> ReaderT (Equiv s d v) (STT s m) d
    forall a b. (a -> b) -> a -> b
    $ Equiv s d v -> Class s d v -> STT s m d
    forall (m :: * -> *) a s c.
    (Monad m, Applicative m, Ord a) =>
    Equiv s c a -> Class s c a -> STT s m c
    S.desc Equiv s d v
    part Class s d v
    x

        remove :: Class s d v -> EquivT s d v m Bool
    remove x :: Class s d v
    x = ReaderT (Equiv s d v) (STT s m) Bool -> EquivT s d v m Bool
    forall s c v (m :: * -> *) a.
    ReaderT (Equiv s c v) (STT s m) a -> EquivT s c v m a
    EquivT (ReaderT (Equiv s d v) (STT s m) Bool -> EquivT s d v m Bool)
    -> ReaderT (Equiv s d v) (STT s m) Bool -> EquivT s d v m Bool
    forall a b. (a -> b) -> a -> b
    $ do
          Equiv s d v
    part <- ReaderT (Equiv s d v) (STT s m) (Equiv s d v)
    forall r (m :: * -> *). MonadReader r m => m r
    ask
          STT s m Bool -> ReaderT (Equiv s d v) (STT s m) Bool
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (STT s m Bool -> ReaderT (Equiv s d v) (STT s m) Bool)
    -> STT s m Bool -> ReaderT (Equiv s d v) (STT s m) Bool
    forall a b. (a -> b) -> a -> b
    $ Equiv s d v -> Class s d v -> STT s m Bool
    forall (m :: * -> *) a s c.
    (Monad m, Applicative m, Ord a) =>
    Equiv s c a -> Class s c a -> STT s m Bool
    S.remove Equiv s d v
    part Class s d v
    x

    instance (MonadEquiv c v d m, Monoid w) => MonadEquiv c v d (WriterT w m) where
        equivalent :: v -> v -> WriterT w m Bool
    equivalent x :: v
    x y :: v
    y = m Bool -> WriterT w m Bool
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (m Bool -> WriterT w m Bool) -> m Bool -> WriterT w m Bool
    forall a b. (a -> b) -> a -> b
    $ v -> v -> m Bool
    forall c v d (m :: * -> *). MonadEquiv c v d m => v -> v -> m Bool
    equivalent v
    x v
    y
        classDesc :: v -> WriterT w m d
    classDesc = m d -> WriterT w m d
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (m d -> WriterT w m d) -> (v -> m d) -> v -> WriterT w m d
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . v -> m d
    forall c v d (m :: * -> *). MonadEquiv c v d m => v -> m d
    classDesc
        equateAll :: [v] -> WriterT w m ()
    equateAll x :: [v]
    x = m () -> WriterT w m ()
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (m () -> WriterT w m ()) -> m () -> WriterT w m ()
    forall a b. (a -> b) -> a -> b
    $ [v] -> m ()
    forall c v d (m :: * -> *). MonadEquiv c v d m => [v] -> m ()
    equateAll [v]
    x
        equate :: v -> v -> WriterT w m ()
    equate x :: v
    x y :: v
    y = m () -> WriterT w m ()
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (m () -> WriterT w m ()) -> m () -> WriterT w m ()
    forall a b. (a -> b) -> a -> b
    $ v -> v -> m ()
    forall c v d (m :: * -> *). MonadEquiv c v d m => v -> v -> m ()
    equate v
    x v
    y
        removeClass :: v -> WriterT w m Bool
    removeClass x :: v
    x = m Bool -> WriterT w m Bool
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (m Bool -> WriterT w m Bool) -> m Bool -> WriterT w m Bool
    forall a b. (a -> b) -> a -> b
    $ v -> m Bool
    forall c v d (m :: * -> *). MonadEquiv c v d m => v -> m Bool
    removeClass v
    x
        getClass :: v -> WriterT w m c
    getClass x :: v
    x = m c -> WriterT w m c
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (m c -> WriterT w m c) -> m c -> WriterT w m c
    forall a b. (a -> b) -> a -> b
    $ v -> m c
    forall c v d (m :: * -> *). MonadEquiv c v d m => v -> m c
    getClass v
    x
        combineAll :: [c] -> WriterT w m ()
    combineAll x :: [c]
    x = m () -> WriterT w m ()
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (m () -> WriterT w m ()) -> m () -> WriterT w m ()
    forall a b. (a -> b) -> a -> b
    $ [c] -> m ()
    forall c v d (m :: * -> *). MonadEquiv c v d m => [c] -> m ()
    combineAll [c]
    x
        combine :: c -> c -> WriterT w m c
    combine x :: c
    x y :: c
    y = m c -> WriterT w m c
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (m c -> WriterT w m c) -> m c -> WriterT w m c
    forall a b. (a -> b) -> a -> b
    $ c -> c -> m c
    forall c v d (m :: * -> *). MonadEquiv c v d m => c -> c -> m c
    combine c
    x c
    y
        x :: c
    x === :: c -> c -> WriterT w m Bool
    === y :: c
    y = m Bool -> WriterT w m Bool
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (m Bool -> WriterT w m Bool) -> m Bool -> WriterT w m Bool
    forall a b. (a -> b) -> a -> b
    $ c -> c -> m Bool
    forall c v d (m :: * -> *). MonadEquiv c v d m => c -> c -> m Bool
    (===) c
    x c
    y
        desc :: c -> WriterT w m d
    desc x :: c
    x = m d -> WriterT w m d
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (m d -> WriterT w m d) -> m d -> WriterT w m d
    forall a b. (a -> b) -> a -> b
    $ c -> m d
    forall c v d (m :: * -> *). MonadEquiv c v d m => c -> m d
    desc c
    x
        remove :: c -> WriterT w m Bool
    remove x :: c
    x = m Bool -> WriterT w m Bool
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (m Bool -> WriterT w m Bool) -> m Bool -> WriterT w m Bool
    forall a b. (a -> b) -> a -> b
    $ c -> m Bool
    forall c v d (m :: * -> *). MonadEquiv c v d m => c -> m Bool
    remove c
    x

    instance (MonadEquiv c v d m, Error e) => MonadEquiv c v d (ErrorT e m) where
        equivalent :: v -> v -> ErrorT e m Bool
    equivalent x :: v
    x y :: v
    y = m Bool -> ErrorT e m Bool
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (m Bool -> ErrorT e m Bool) -> m Bool -> ErrorT e m Bool
    forall a b. (a -> b) -> a -> b
    $ v -> v -> m Bool
    forall c v d (m :: * -> *). MonadEquiv c v d m => v -> v -> m Bool
    equivalent v
    x v
    y
        classDesc :: v -> ErrorT e m d
    classDesc = m d -> ErrorT e m d
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (m d -> ErrorT e m d) -> (v -> m d) -> v -> ErrorT e m d
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . v -> m d
    forall c v d (m :: * -> *). MonadEquiv c v d m => v -> m d
    classDesc
        equateAll :: [v] -> ErrorT e m ()
    equateAll x :: [v]
    x = m () -> ErrorT e m ()
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (m () -> ErrorT e m ()) -> m () -> ErrorT e m ()
    forall a b. (a -> b) -> a -> b
    $ [v] -> m ()
    forall c v d (m :: * -> *). MonadEquiv c v d m => [v] -> m ()
    equateAll [v]
    x
        equate :: v -> v -> ErrorT e m ()
    equate x :: v
    x y :: v
    y = m () -> ErrorT e m ()
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (m () -> ErrorT e m ()) -> m () -> ErrorT e m ()
    forall a b. (a -> b) -> a -> b
    $ v -> v -> m ()
    forall c v d (m :: * -> *). MonadEquiv c v d m => v -> v -> m ()
    equate v
    x v
    y
        removeClass :: v -> ErrorT e m Bool
    removeClass x :: v
    x = m Bool -> ErrorT e m Bool
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (m Bool -> ErrorT e m Bool) -> m Bool -> ErrorT e m Bool
    forall a b. (a -> b) -> a -> b
    $ v -> m Bool
    forall c v d (m :: * -> *). MonadEquiv c v d m => v -> m Bool
    removeClass v
    x
        getClass :: v -> ErrorT e m c
    getClass x :: v
    x = m c -> ErrorT e m c
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (m c -> ErrorT e m c) -> m c -> ErrorT e m c
    forall a b. (a -> b) -> a -> b
    $ v -> m c
    forall c v d (m :: * -> *). MonadEquiv c v d m => v -> m c
    getClass v
    x
        combineAll :: [c] -> ErrorT e m ()
    combineAll x :: [c]
    x = m () -> ErrorT e m ()
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (m () -> ErrorT e m ()) -> m () -> ErrorT e m ()
    forall a b. (a -> b) -> a -> b
    $ [c] -> m ()
    forall c v d (m :: * -> *). MonadEquiv c v d m => [c] -> m ()
    combineAll [c]
    x
        combine :: c -> c -> ErrorT e m c
    combine x :: c
    x y :: c
    y = m c -> ErrorT e m c
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (m c -> ErrorT e m c) -> m c -> ErrorT e m c
    forall a b. (a -> b) -> a -> b
    $ c -> c -> m c
    forall c v d (m :: * -> *). MonadEquiv c v d m => c -> c -> m c
    combine c
    x c
    y
        x :: c
    x === :: c -> c -> ErrorT e m Bool
    === y :: c
    y = m Bool -> ErrorT e m Bool
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (m Bool -> ErrorT e m Bool) -> m Bool -> ErrorT e m Bool
    forall a b. (a -> b) -> a -> b
    $ c -> c -> m Bool
    forall c v d (m :: * -> *). MonadEquiv c v d m => c -> c -> m Bool
    (===) c
    x c
    y
        desc :: c -> ErrorT e m d
    desc x :: c
    x = m d -> ErrorT e m d
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (m d -> ErrorT e m d) -> m d -> ErrorT e m d
    forall a b. (a -> b) -> a -> b
    $ c -> m d
    forall c v d (m :: * -> *). MonadEquiv c v d m => c -> m d
    desc c
    x
        remove :: c -> ErrorT e m Bool
    remove x :: c
    x = m Bool -> ErrorT e m Bool
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (m Bool -> ErrorT e m Bool) -> m Bool -> ErrorT e m Bool
    forall a b. (a -> b) -> a -> b
    $ c -> m Bool
    forall c v d (m :: * -> *). MonadEquiv c v d m => c -> m Bool
    remove c
    x

    instance (MonadEquiv c v d m) => MonadEquiv c v d (ExceptT e m) where
        equivalent :: v -> v -> ExceptT e m Bool
    equivalent x :: v
    x y :: v
    y = m Bool -> ExceptT e m Bool
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (m Bool -> ExceptT e m Bool) -> m Bool -> ExceptT e m Bool
    forall a b. (a -> b) -> a -> b
    $ v -> v -> m Bool
    forall c v d (m :: * -> *). MonadEquiv c v d m => v -> v -> m Bool
    equivalent v
    x v
    y
        classDesc :: v -> ExceptT e m d
    classDesc = m d -> ExceptT e m d
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (m d -> ExceptT e m d) -> (v -> m d) -> v -> ExceptT e m d
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . v -> m d
    forall c v d (m :: * -> *). MonadEquiv c v d m => v -> m d
    classDesc
        equateAll :: [v] -> ExceptT e m ()
    equateAll x :: [v]
    x = m () -> ExceptT e m ()
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (m () -> ExceptT e m ()) -> m () -> ExceptT e m ()
    forall a b. (a -> b) -> a -> b
    $ [v] -> m ()
    forall c v d (m :: * -> *). MonadEquiv c v d m => [v] -> m ()
    equateAll [v]
    x
        equate :: v -> v -> ExceptT e m ()
    equate x :: v
    x y :: v
    y = m () -> ExceptT e m ()
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (m () -> ExceptT e m ()) -> m () -> ExceptT e m ()
    forall a b. (a -> b) -> a -> b
    $ v -> v -> m ()
    forall c v d (m :: * -> *). MonadEquiv c v d m => v -> v -> m ()
    equate v
    x v
    y
        removeClass :: v -> ExceptT e m Bool
    removeClass x :: v
    x = m Bool -> ExceptT e m Bool
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (m Bool -> ExceptT e m Bool) -> m Bool -> ExceptT e m Bool
    forall a b. (a -> b) -> a -> b
    $ v -> m Bool
    forall c v d (m :: * -> *). MonadEquiv c v d m => v -> m Bool
    removeClass v
    x
        getClass :: v -> ExceptT e m c
    getClass x :: v
    x = m c -> ExceptT e m c
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (m c -> ExceptT e m c) -> m c -> ExceptT e m c
    forall a b. (a -> b) -> a -> b
    $ v -> m c
    forall c v d (m :: * -> *). MonadEquiv c v d m => v -> m c
    getClass v
    x
        combineAll :: [c] -> ExceptT e m ()
    combineAll x :: [c]
    x = m () -> ExceptT e m ()
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (m () -> ExceptT e m ()) -> m () -> ExceptT e m ()
    forall a b. (a -> b) -> a -> b
    $ [c] -> m ()
    forall c v d (m :: * -> *). MonadEquiv c v d m => [c] -> m ()
    combineAll [c]
    x
        combine :: c -> c -> ExceptT e m c
    combine x :: c
    x y :: c
    y = m c -> ExceptT e m c
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (m c -> ExceptT e m c) -> m c -> ExceptT e m c
    forall a b. (a -> b) -> a -> b
    $ c -> c -> m c
    forall c v d (m :: * -> *). MonadEquiv c v d m => c -> c -> m c
    combine c
    x c
    y
        x :: c
    x === :: c -> c -> ExceptT e m Bool
    === y :: c
    y = m Bool -> ExceptT e m Bool
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (m Bool -> ExceptT e m Bool) -> m Bool -> ExceptT e m Bool
    forall a b. (a -> b) -> a -> b
    $ c -> c -> m Bool
    forall c v d (m :: * -> *). MonadEquiv c v d m => c -> c -> m Bool
    (===) c
    x c
    y
        desc :: c -> ExceptT e m d
    desc x :: c
    x = m d -> ExceptT e m d
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (m d -> ExceptT e m d) -> m d -> ExceptT e m d
    forall a b. (a -> b) -> a -> b
    $ c -> m d
    forall c v d (m :: * -> *). MonadEquiv c v d m => c -> m d
    desc c
    x
        remove :: c -> ExceptT e m Bool
    remove x :: c
    x = m Bool -> ExceptT e m Bool
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (m Bool -> ExceptT e m Bool) -> m Bool -> ExceptT e m Bool
    forall a b. (a -> b) -> a -> b
    $ c -> m Bool
    forall c v d (m :: * -> *). MonadEquiv c v d m => c -> m Bool
    remove c
    x

    instance (MonadEquiv c v d m) => MonadEquiv c v d (StateT s m) where
        equivalent :: v -> v -> StateT s m Bool
    equivalent x :: v
    x y :: v
    y = m Bool -> StateT s m Bool
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (m Bool -> StateT s m Bool) -> m Bool -> StateT s m Bool
    forall a b. (a -> b) -> a -> b
    $ v -> v -> m Bool
    forall c v d (m :: * -> *). MonadEquiv c v d m => v -> v -> m Bool
    equivalent v
    x v
    y
        classDesc :: v -> StateT s m d
    classDesc = m d -> StateT s m d
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (m d -> StateT s m d) -> (v -> m d) -> v -> StateT s m d
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . v -> m d
    forall c v d (m :: * -> *). MonadEquiv c v d m => v -> m d
    classDesc
        equateAll :: [v] -> StateT s m ()
    equateAll x :: [v]
    x = m () -> StateT s m ()
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (m () -> StateT s m ()) -> m () -> StateT s m ()
    forall a b. (a -> b) -> a -> b
    $ [v] -> m ()
    forall c v d (m :: * -> *). MonadEquiv c v d m => [v] -> m ()
    equateAll [v]
    x
        equate :: v -> v -> StateT s m ()
    equate x :: v
    x y :: v
    y = m () -> StateT s m ()
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (m () -> StateT s m ()) -> m () -> StateT s m ()
    forall a b. (a -> b) -> a -> b
    $ v -> v -> m ()
    forall c v d (m :: * -> *). MonadEquiv c v d m => v -> v -> m ()
    equate v
    x v
    y
        removeClass :: v -> StateT s m Bool
    removeClass x :: v
    x = m Bool -> StateT s m Bool
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (m Bool -> StateT s m Bool) -> m Bool -> StateT s m Bool
    forall a b. (a -> b) -> a -> b
    $ v -> m Bool
    forall c v d (m :: * -> *). MonadEquiv c v d m => v -> m Bool
    removeClass v
    x
        getClass :: v -> StateT s m c
    getClass x :: v
    x = m c -> StateT s m c
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (m c -> StateT s m c) -> m c -> StateT s m c
    forall a b. (a -> b) -> a -> b
    $ v -> m c
    forall c v d (m :: * -> *). MonadEquiv c v d m => v -> m c
    getClass v
    x
        combineAll :: [c] -> StateT s m ()
    combineAll x :: [c]
    x = m () -> StateT s m ()
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (m () -> StateT s m ()) -> m () -> StateT s m ()
    forall a b. (a -> b) -> a -> b
    $ [c] -> m ()
    forall c v d (m :: * -> *). MonadEquiv c v d m => [c] -> m ()
    combineAll [c]
    x
        combine :: c -> c -> StateT s m c
    combine x :: c
    x y :: c
    y = m c -> StateT s m c
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (m c -> StateT s m c) -> m c -> StateT s m c
    forall a b. (a -> b) -> a -> b
    $ c -> c -> m c
    forall c v d (m :: * -> *). MonadEquiv c v d m => c -> c -> m c
    combine c
    x c
    y
        x :: c
    x === :: c -> c -> StateT s m Bool
    === y :: c
    y = m Bool -> StateT s m Bool
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (m Bool -> StateT s m Bool) -> m Bool -> StateT s m Bool
    forall a b. (a -> b) -> a -> b
    $ c -> c -> m Bool
    forall c v d (m :: * -> *). MonadEquiv c v d m => c -> c -> m Bool
    (===) c
    x c
    y
        desc :: c -> StateT s m d
    desc x :: c
    x = m d -> StateT s m d
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (m d -> StateT s m d) -> m d -> StateT s m d
    forall a b. (a -> b) -> a -> b
    $ c -> m d
    forall c v d (m :: * -> *). MonadEquiv c v d m => c -> m d
    desc c
    x
        remove :: c -> StateT s m Bool
    remove x :: c
    x = m Bool -> StateT s m Bool
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (m Bool -> StateT s m Bool) -> m Bool -> StateT s m Bool
    forall a b. (a -> b) -> a -> b
    $ c -> m Bool
    forall c v d (m :: * -> *). MonadEquiv c v d m => c -> m Bool
    remove c
    x

    instance (MonadEquiv c v d m) => MonadEquiv c v d (ReaderT r m) where
        equivalent :: v -> v -> ReaderT r m Bool
    equivalent x :: v
    x y :: v
    y = m Bool -> ReaderT r m Bool
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (m Bool -> ReaderT r m Bool) -> m Bool -> ReaderT r m Bool
    forall a b. (a -> b) -> a -> b
    $ v -> v -> m Bool
    forall c v d (m :: * -> *). MonadEquiv c v d m => v -> v -> m Bool
    equivalent v
    x v
    y
        classDesc :: v -> ReaderT r m d
    classDesc = m d -> ReaderT r m d
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (m d -> ReaderT r m d) -> (v -> m d) -> v -> ReaderT r m d
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . v -> m d
    forall c v d (m :: * -> *). MonadEquiv c v d m => v -> m d
    classDesc
        equateAll :: [v] -> ReaderT r m ()
    equateAll x :: [v]
    x = m () -> ReaderT r m ()
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (m () -> ReaderT r m ()) -> m () -> ReaderT r m ()
    forall a b. (a -> b) -> a -> b
    $ [v] -> m ()
    forall c v d (m :: * -> *). MonadEquiv c v d m => [v] -> m ()
    equateAll [v]
    x
        equate :: v -> v -> ReaderT r m ()
    equate x :: v
    x y :: v
    y = m () -> ReaderT r m ()
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (m () -> ReaderT r m ()) -> m () -> ReaderT r m ()
    forall a b. (a -> b) -> a -> b
    $ v -> v -> m ()
    forall c v d (m :: * -> *). MonadEquiv c v d m => v -> v -> m ()
    equate v
    x v
    y
        removeClass :: v -> ReaderT r m Bool
    removeClass x :: v
    x = m Bool -> ReaderT r m Bool
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (m Bool -> ReaderT r m Bool) -> m Bool -> ReaderT r m Bool
    forall a b. (a -> b) -> a -> b
    $ v -> m Bool
    forall c v d (m :: * -> *). MonadEquiv c v d m => v -> m Bool
    removeClass v
    x
        getClass :: v -> ReaderT r m c
    getClass x :: v
    x = m c -> ReaderT r m c
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (m c -> ReaderT r m c) -> m c -> ReaderT r m c
    forall a b. (a -> b) -> a -> b
    $ v -> m c
    forall c v d (m :: * -> *). MonadEquiv c v d m => v -> m c
    getClass v
    x
        combineAll :: [c] -> ReaderT r m ()
    combineAll x :: [c]
    x = m () -> ReaderT r m ()
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (m () -> ReaderT r m ()) -> m () -> ReaderT r m ()
    forall a b. (a -> b) -> a -> b
    $ [c] -> m ()
    forall c v d (m :: * -> *). MonadEquiv c v d m => [c] -> m ()
    combineAll [c]
    x
        combine :: c -> c -> ReaderT r m c
    combine x :: c
    x y :: c
    y = m c -> ReaderT r m c
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (m c -> ReaderT r m c) -> m c -> ReaderT r m c
    forall a b. (a -> b) -> a -> b
    $ c -> c -> m c
    forall c v d (m :: * -> *). MonadEquiv c v d m => c -> c -> m c
    combine c
    x c
    y
        x :: c
    x === :: c -> c -> ReaderT r m Bool
    === y :: c
    y = m Bool -> ReaderT r m Bool
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (m Bool -> ReaderT r m Bool) -> m Bool -> ReaderT r m Bool
    forall a b. (a -> b) -> a -> b
    $ c -> c -> m Bool
    forall c v d (m :: * -> *). MonadEquiv c v d m => c -> c -> m Bool
    (===) c
    x c
    y
        desc :: c -> ReaderT r m d
    desc x :: c
    x = m d -> ReaderT r m d
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (m d -> ReaderT r m d) -> m d -> ReaderT r m d
    forall a b. (a -> b) -> a -> b
    $ c -> m d
    forall c v d (m :: * -> *). MonadEquiv c v d m => c -> m d
    desc c
    x
        remove :: c -> ReaderT r m Bool
    remove x :: c
    x = m Bool -> ReaderT r m Bool
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (m Bool -> ReaderT r m Bool) -> m Bool -> ReaderT r m Bool
    forall a b. (a -> b) -> a -> b
    $ c -> m Bool
    forall c v d (m :: * -> *). MonadEquiv c v d m => c -> m Bool
    remove c
    x