{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE QuantifiedConstraints #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}

-- |
-- Module      :   Grisette.Internal.Internal.Impl.Unified.Class.UnifiedSimpleMergeable
-- Copyright   :   (c) Sirui Lu 2024
-- License     :   BSD-3-Clause (see the LICENSE file)
--
-- Maintainer  :   siruilu@cs.washington.edu
-- Stability   :   Experimental
-- Portability :   GHC only
module Grisette.Internal.Internal.Impl.Unified.Class.UnifiedSimpleMergeable
  ( mrgIf,
    liftUnion,
    mrgIte,
    mrgIte1,
    liftMrgIte,
    mrgIte2,
    liftMrgIte2,
    simpleMerge,
    (.#),
    onUnion,
    onUnion2,
    onUnion3,
    onUnion4,
  )
where

import Control.Monad.Cont (ContT)
import Control.Monad.Except (ExceptT)
import Control.Monad.Identity (Identity, IdentityT)
import Control.Monad.Trans.Maybe (MaybeT)
import qualified Control.Monad.Trans.RWS.Lazy as RWSLazy
import qualified Control.Monad.Trans.RWS.Strict as RWSStrict
import Control.Monad.Trans.Reader (ReaderT)
import qualified Control.Monad.Trans.State.Lazy as StateLazy
import qualified Control.Monad.Trans.State.Strict as StateStrict
import qualified Control.Monad.Trans.Writer.Lazy as WriterLazy
import qualified Control.Monad.Trans.Writer.Strict as WriterStrict
import Data.Kind (Constraint)
import Data.Type.Bool (If)
import Grisette.Internal.Core.Control.Exception (AssertionError)
import Grisette.Internal.Core.Data.Class.Function (Function ((#)))
import Grisette.Internal.Core.Data.Class.GenSym (FreshT)
import Grisette.Internal.Core.Data.Class.Mergeable (Mergeable, Mergeable1)
import Grisette.Internal.Core.Data.Class.SimpleMergeable
  ( SimpleMergeable,
    SimpleMergeable1,
    SimpleMergeable2,
    SymBranching,
  )
import qualified Grisette.Internal.Core.Data.Class.SimpleMergeable
import qualified Grisette.Internal.Core.Data.Class.SimpleMergeable as Grisette
import Grisette.Internal.Core.Data.Class.TryMerge
  ( TryMerge,
    mrgSingle,
    tryMerge,
  )
import Grisette.Internal.Core.Data.Class.UnionView
  ( UnionView,
    pattern If,
    pattern Single,
  )
import qualified Grisette.Internal.Core.Data.Class.UnionView as Grisette
import Grisette.Internal.Internal.Decl.Unified.Class.UnifiedSimpleMergeable
  ( UnifiedBranching (withBaseBranching),
    UnifiedSimpleMergeable (withBaseSimpleMergeable),
    UnifiedSimpleMergeable1 (withBaseSimpleMergeable1),
    UnifiedSimpleMergeable2 (withBaseSimpleMergeable2),
  )
import Grisette.Internal.TH.Derivation.Derive (derive)
import Grisette.Internal.Unified.Class.UnionViewMode (UnionViewMode)
import Grisette.Internal.Unified.EvalModeTag (IsConMode)
import Grisette.Internal.Unified.UnifiedBool (UnifiedBool (GetBool))
import Grisette.Internal.Unified.Util (DecideEvalMode, withMode)

-- | Unified `Grisette.mrgIf`.
--
-- This function isn't able to infer the mode of the boolean variable, so you
-- need to provide the mode explicitly. For example:
--
-- > mrgIf @mode (a .== b) ...
-- > mrgIf (a .== b :: SymBool) ...
-- > mrgIf (a .== b :: GetBool mode) ...
mrgIf ::
  forall mode a m.
  (DecideEvalMode mode, Mergeable a, UnifiedBranching mode m) =>
  GetBool mode ->
  m a ->
  m a ->
  m a
mrgIf :: forall (mode :: EvalModeTag) a (m :: * -> *).
(DecideEvalMode mode, Mergeable a, UnifiedBranching mode m) =>
GetBool mode -> m a -> m a -> m a
mrgIf GetBool mode
c m a
t m a
e =
  forall (mode :: EvalModeTag) r.
DecideEvalMode mode =>
((mode ~ 'C) => r) -> ((mode ~ 'S) => r) -> r
withMode @mode
    (if Bool
GetBool mode
c then m a
t else m a
e)
    (forall (mode :: EvalModeTag) (m :: * -> *) r.
UnifiedBranching mode m =>
(If (IsConMode mode) (TryMerge m) (SymBranching m) => r) -> r
withBaseBranching @mode @m ((If (IsConMode mode) (TryMerge m) (SymBranching m) => m a) -> m a)
-> (If (IsConMode mode) (TryMerge m) (SymBranching m) => m a)
-> m a
forall a b. (a -> b) -> a -> b
$ SymBool -> m a -> m a -> m a
forall (u :: * -> *) a.
(SymBranching u, Mergeable a) =>
SymBool -> u a -> u a -> u a
Grisette.mrgIf SymBool
GetBool mode
c m a
t m a
e)
{-# INLINE mrgIf #-}

-- | Unified lifting of a base monad.
liftUnion ::
  forall mode a m u.
  ( Applicative m,
    UnifiedBranching mode m,
    Mergeable a,
    UnionView u,
    UnionViewMode mode u
  ) =>
  u a ->
  m a
liftUnion :: forall (mode :: EvalModeTag) a (m :: * -> *) (u :: * -> *).
(Applicative m, UnifiedBranching mode m, Mergeable a, UnionView u,
 UnionViewMode mode u) =>
u a -> m a
liftUnion u a
b =
  forall (mode :: EvalModeTag) r.
DecideEvalMode mode =>
((mode ~ 'C) => r) -> ((mode ~ 'S) => r) -> r
withMode @mode
    ( forall (mode :: EvalModeTag) (m :: * -> *) r.
UnifiedBranching mode m =>
(If (IsConMode mode) (TryMerge m) (SymBranching m) => r) -> r
withBaseBranching @mode @m ((If (IsConMode mode) (TryMerge m) (SymBranching m) => m a) -> m a)
-> (If (IsConMode mode) (TryMerge m) (SymBranching m) => m a)
-> m a
forall a b. (a -> b) -> a -> b
$ case u a
b of
        Single a
x -> a -> m a
forall (m :: * -> *) a.
(TryMerge m, Applicative m, Mergeable a) =>
a -> m a
mrgSingle a
x
        If {} ->
          [Char] -> m a
forall a. HasCallStack => [Char] -> a
error [Char]
"liftUnion: If case should not happen under concrete mode"
    )
    (forall (mode :: EvalModeTag) (m :: * -> *) r.
UnifiedBranching mode m =>
(If (IsConMode mode) (TryMerge m) (SymBranching m) => r) -> r
withBaseBranching @mode @m ((If (IsConMode mode) (TryMerge m) (SymBranching m) => m a) -> m a)
-> (If (IsConMode mode) (TryMerge m) (SymBranching m) => m a)
-> m a
forall a b. (a -> b) -> a -> b
$ u a -> m a
forall a (u :: * -> *) (m :: * -> *).
(Mergeable a, UnionView u, Applicative m, SymBranching m) =>
u a -> m a
Grisette.liftUnion u a
b)
{-# INLINE liftUnion #-}

-- | Unified merge of simply mergeable values in the base monad.
simpleMerge ::
  forall mode a u.
  ( UnifiedSimpleMergeable mode a,
    UnionView u,
    UnionViewMode mode u
  ) =>
  u a ->
  a
simpleMerge :: forall (mode :: EvalModeTag) a (u :: * -> *).
(UnifiedSimpleMergeable mode a, UnionView u,
 UnionViewMode mode u) =>
u a -> a
simpleMerge =
  forall (mode :: EvalModeTag) r.
DecideEvalMode mode =>
((mode ~ 'C) => r) -> ((mode ~ 'S) => r) -> r
withMode @mode
    ( \case
        Single a
x -> a
x
        If {} ->
          [Char] -> a
forall a. HasCallStack => [Char] -> a
error [Char]
"simpleMerge: If case should not happen under concrete mode"
    )
    (forall (mode :: EvalModeTag) a r.
UnifiedSimpleMergeable mode a =>
(If (IsConMode mode) (() :: Constraint) (SimpleMergeable a) => r)
-> r
withBaseSimpleMergeable @mode @a u a -> a
If (IsConMode mode) (() :: Constraint) (SimpleMergeable a) =>
u a -> a
forall (u :: * -> *) a.
(SimpleMergeable a, UnionView u) =>
u a -> a
Grisette.simpleMerge)

(.#) ::
  (Function f a r, UnifiedSimpleMergeable mode r, UnionView u, UnionViewMode mode u) =>
  f ->
  u a ->
  r
.# :: forall f a r (mode :: EvalModeTag) (u :: * -> *).
(Function f a r, UnifiedSimpleMergeable mode r, UnionView u,
 UnionViewMode mode u) =>
f -> u a -> r
(.#) f
f u a
u = u r -> r
forall (mode :: EvalModeTag) a (u :: * -> *).
(UnifiedSimpleMergeable mode a, UnionView u,
 UnionViewMode mode u) =>
u a -> a
simpleMerge (u r -> r) -> u r -> r
forall a b. (a -> b) -> a -> b
$ (a -> r) -> u a -> u r
forall a b. (a -> b) -> u a -> u b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (f
f f -> a -> r
forall f arg ret. Function f arg ret => f -> arg -> ret
#) u a
u
{-# INLINE (.#) #-}

infixl 9 .#

onUnion ::
  ( UnifiedSimpleMergeable mode r,
    UnifiedBranching mode u,
    Mergeable a,
    UnionView u,
    UnionViewMode mode u
  ) =>
  (a -> r) -> (u a -> r)
onUnion :: forall (mode :: EvalModeTag) r (u :: * -> *) a.
(UnifiedSimpleMergeable mode r, UnifiedBranching mode u,
 Mergeable a, UnionView u, UnionViewMode mode u) =>
(a -> r) -> u a -> r
onUnion a -> r
f = u r -> r
forall (mode :: EvalModeTag) a (u :: * -> *).
(UnifiedSimpleMergeable mode a, UnionView u,
 UnionViewMode mode u) =>
u a -> a
simpleMerge (u r -> r) -> (u a -> u r) -> u a -> r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> r) -> u a -> u r
forall a b. (a -> b) -> u a -> u b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> r
f (u a -> u r) -> (u a -> u a) -> u a -> u r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. u a -> u a
forall (m :: * -> *) a. (TryMerge m, Mergeable a) => m a -> m a
tryMerge

onUnion2 ::
  ( UnifiedSimpleMergeable mode r,
    UnifiedBranching mode u,
    Mergeable a,
    Mergeable b,
    UnionView u,
    UnionViewMode mode u
  ) =>
  (a -> b -> r) -> (u a -> u b -> r)
onUnion2 :: forall (mode :: EvalModeTag) r (u :: * -> *) a b.
(UnifiedSimpleMergeable mode r, UnifiedBranching mode u,
 Mergeable a, Mergeable b, UnionView u, UnionViewMode mode u) =>
(a -> b -> r) -> u a -> u b -> r
onUnion2 a -> b -> r
f u a
ua u b
ub = u r -> r
forall (mode :: EvalModeTag) a (u :: * -> *).
(UnifiedSimpleMergeable mode a, UnionView u,
 UnionViewMode mode u) =>
u a -> a
simpleMerge (u r -> r) -> u r -> r
forall a b. (a -> b) -> a -> b
$ a -> b -> r
f (a -> b -> r) -> u a -> u (b -> r)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> u a -> u a
forall (m :: * -> *) a. (TryMerge m, Mergeable a) => m a -> m a
tryMerge u a
ua u (b -> r) -> u b -> u r
forall a b. u (a -> b) -> u a -> u b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> u b -> u b
forall (m :: * -> *) a. (TryMerge m, Mergeable a) => m a -> m a
tryMerge u b
ub

onUnion3 ::
  ( UnifiedSimpleMergeable mode r,
    UnifiedBranching mode u,
    Mergeable a,
    Mergeable b,
    Mergeable c,
    UnionView u,
    UnionViewMode mode u
  ) =>
  (a -> b -> c -> r) -> (u a -> u b -> u c -> r)
onUnion3 :: forall (mode :: EvalModeTag) r (u :: * -> *) a b c.
(UnifiedSimpleMergeable mode r, UnifiedBranching mode u,
 Mergeable a, Mergeable b, Mergeable c, UnionView u,
 UnionViewMode mode u) =>
(a -> b -> c -> r) -> u a -> u b -> u c -> r
onUnion3 a -> b -> c -> r
f u a
ua u b
ub u c
uc = u r -> r
forall (mode :: EvalModeTag) a (u :: * -> *).
(UnifiedSimpleMergeable mode a, UnionView u,
 UnionViewMode mode u) =>
u a -> a
simpleMerge (u r -> r) -> u r -> r
forall a b. (a -> b) -> a -> b
$ a -> b -> c -> r
f (a -> b -> c -> r) -> u a -> u (b -> c -> r)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> u a -> u a
forall (m :: * -> *) a. (TryMerge m, Mergeable a) => m a -> m a
tryMerge u a
ua u (b -> c -> r) -> u b -> u (c -> r)
forall a b. u (a -> b) -> u a -> u b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> u b -> u b
forall (m :: * -> *) a. (TryMerge m, Mergeable a) => m a -> m a
tryMerge u b
ub u (c -> r) -> u c -> u r
forall a b. u (a -> b) -> u a -> u b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> u c -> u c
forall (m :: * -> *) a. (TryMerge m, Mergeable a) => m a -> m a
tryMerge u c
uc

onUnion4 ::
  ( UnifiedSimpleMergeable mode r,
    UnifiedBranching mode u,
    Mergeable a,
    Mergeable b,
    Mergeable c,
    Mergeable d,
    UnionView u,
    UnionViewMode mode u
  ) =>
  (a -> b -> c -> d -> r) -> (u a -> u b -> u c -> u d -> r)
onUnion4 :: forall (mode :: EvalModeTag) r (u :: * -> *) a b c d.
(UnifiedSimpleMergeable mode r, UnifiedBranching mode u,
 Mergeable a, Mergeable b, Mergeable c, Mergeable d, UnionView u,
 UnionViewMode mode u) =>
(a -> b -> c -> d -> r) -> u a -> u b -> u c -> u d -> r
onUnion4 a -> b -> c -> d -> r
f u a
ua u b
ub u c
uc u d
ud = u r -> r
forall (mode :: EvalModeTag) a (u :: * -> *).
(UnifiedSimpleMergeable mode a, UnionView u,
 UnionViewMode mode u) =>
u a -> a
simpleMerge (u r -> r) -> u r -> r
forall a b. (a -> b) -> a -> b
$ a -> b -> c -> d -> r
f (a -> b -> c -> d -> r) -> u a -> u (b -> c -> d -> r)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> u a -> u a
forall (m :: * -> *) a. (TryMerge m, Mergeable a) => m a -> m a
tryMerge u a
ua u (b -> c -> d -> r) -> u b -> u (c -> d -> r)
forall a b. u (a -> b) -> u a -> u b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> u b -> u b
forall (m :: * -> *) a. (TryMerge m, Mergeable a) => m a -> m a
tryMerge u b
ub u (c -> d -> r) -> u c -> u (d -> r)
forall a b. u (a -> b) -> u a -> u b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> u c -> u c
forall (m :: * -> *) a. (TryMerge m, Mergeable a) => m a -> m a
tryMerge u c
uc u (d -> r) -> u d -> u r
forall a b. u (a -> b) -> u a -> u b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> u d -> u d
forall (m :: * -> *) a. (TryMerge m, Mergeable a) => m a -> m a
tryMerge u d
ud

-- | Unified `Grisette.mrgIte`.
mrgIte ::
  forall mode a.
  (UnifiedSimpleMergeable mode a) =>
  GetBool mode ->
  a ->
  a ->
  a
mrgIte :: forall (mode :: EvalModeTag) a.
UnifiedSimpleMergeable mode a =>
GetBool mode -> a -> a -> a
mrgIte GetBool mode
c a
t a
e =
  forall (mode :: EvalModeTag) r.
DecideEvalMode mode =>
((mode ~ 'C) => r) -> ((mode ~ 'S) => r) -> r
withMode @mode
    (if Bool
GetBool mode
c then a
t else a
e)
    ( forall (mode :: EvalModeTag) a r.
UnifiedSimpleMergeable mode a =>
(If (IsConMode mode) (() :: Constraint) (SimpleMergeable a) => r)
-> r
withBaseSimpleMergeable @mode @a ((If (IsConMode mode) (() :: Constraint) (SimpleMergeable a) => a)
 -> a)
-> (If (IsConMode mode) (() :: Constraint) (SimpleMergeable a) =>
    a)
-> a
forall a b. (a -> b) -> a -> b
$
        SymBool -> a -> a -> a
forall a. SimpleMergeable a => SymBool -> a -> a -> a
Grisette.Internal.Core.Data.Class.SimpleMergeable.mrgIte SymBool
GetBool mode
c a
t a
e
    )

-- | Unified `Grisette.mrgIte1`.
mrgIte1 ::
  forall mode f a.
  ( UnifiedSimpleMergeable1 mode f,
    UnifiedSimpleMergeable mode a
  ) =>
  GetBool mode ->
  f a ->
  f a ->
  f a
mrgIte1 :: forall (mode :: EvalModeTag) (f :: * -> *) a.
(UnifiedSimpleMergeable1 mode f, UnifiedSimpleMergeable mode a) =>
GetBool mode -> f a -> f a -> f a
mrgIte1 GetBool mode
c f a
t f a
e =
  forall (mode :: EvalModeTag) r.
DecideEvalMode mode =>
((mode ~ 'C) => r) -> ((mode ~ 'S) => r) -> r
withMode @mode
    (if Bool
GetBool mode
c then f a
t else f a
e)
    ( forall (mode :: EvalModeTag) a r.
UnifiedSimpleMergeable mode a =>
(If (IsConMode mode) (() :: Constraint) (SimpleMergeable a) => r)
-> r
withBaseSimpleMergeable @mode @a ((If (IsConMode mode) (() :: Constraint) (SimpleMergeable a) =>
  f a)
 -> f a)
-> (If (IsConMode mode) (() :: Constraint) (SimpleMergeable a) =>
    f a)
-> f a
forall a b. (a -> b) -> a -> b
$
        forall (mode :: EvalModeTag) (f :: * -> *) r.
UnifiedSimpleMergeable1 mode f =>
(If (IsConMode mode) (() :: Constraint) (SimpleMergeable1 f) => r)
-> r
withBaseSimpleMergeable1 @mode @f ((If (IsConMode mode) (() :: Constraint) (SimpleMergeable1 f) =>
  f a)
 -> f a)
-> (If (IsConMode mode) (() :: Constraint) (SimpleMergeable1 f) =>
    f a)
-> f a
forall a b. (a -> b) -> a -> b
$
          SymBool -> f a -> f a -> f a
forall (u :: * -> *) a.
(SimpleMergeable1 u, SimpleMergeable a) =>
SymBool -> u a -> u a -> u a
Grisette.Internal.Core.Data.Class.SimpleMergeable.mrgIte1 SymBool
GetBool mode
c f a
t f a
e
    )

-- | Unified `Grisette.liftMrgIte`.
liftMrgIte ::
  forall mode f a.
  (UnifiedSimpleMergeable1 mode f) =>
  (GetBool mode -> a -> a -> a) ->
  GetBool mode ->
  f a ->
  f a ->
  f a
liftMrgIte :: forall (mode :: EvalModeTag) (f :: * -> *) a.
UnifiedSimpleMergeable1 mode f =>
(GetBool mode -> a -> a -> a) -> GetBool mode -> f a -> f a -> f a
liftMrgIte GetBool mode -> a -> a -> a
f GetBool mode
c f a
t f a
e =
  forall (mode :: EvalModeTag) r.
DecideEvalMode mode =>
((mode ~ 'C) => r) -> ((mode ~ 'S) => r) -> r
withMode @mode
    (if Bool
GetBool mode
c then f a
t else f a
e)
    ( forall (mode :: EvalModeTag) (f :: * -> *) r.
UnifiedSimpleMergeable1 mode f =>
(If (IsConMode mode) (() :: Constraint) (SimpleMergeable1 f) => r)
-> r
withBaseSimpleMergeable1 @mode @f ((If (IsConMode mode) (() :: Constraint) (SimpleMergeable1 f) =>
  f a)
 -> f a)
-> (If (IsConMode mode) (() :: Constraint) (SimpleMergeable1 f) =>
    f a)
-> f a
forall a b. (a -> b) -> a -> b
$
        (SymBool -> a -> a -> a) -> SymBool -> f a -> f a -> f a
forall a. (SymBool -> a -> a -> a) -> SymBool -> f a -> f a -> f a
forall (u :: * -> *) a.
SimpleMergeable1 u =>
(SymBool -> a -> a -> a) -> SymBool -> u a -> u a -> u a
Grisette.Internal.Core.Data.Class.SimpleMergeable.liftMrgIte SymBool -> a -> a -> a
GetBool mode -> a -> a -> a
f SymBool
GetBool mode
c f a
t f a
e
    )

-- | Unified `Grisette.mrgIte2`.
mrgIte2 ::
  forall mode f a b.
  ( UnifiedSimpleMergeable2 mode f,
    UnifiedSimpleMergeable mode a,
    UnifiedSimpleMergeable mode b
  ) =>
  GetBool mode ->
  f a b ->
  f a b ->
  f a b
mrgIte2 :: forall (mode :: EvalModeTag) (f :: * -> * -> *) a b.
(UnifiedSimpleMergeable2 mode f, UnifiedSimpleMergeable mode a,
 UnifiedSimpleMergeable mode b) =>
GetBool mode -> f a b -> f a b -> f a b
mrgIte2 GetBool mode
c f a b
t f a b
e =
  forall (mode :: EvalModeTag) r.
DecideEvalMode mode =>
((mode ~ 'C) => r) -> ((mode ~ 'S) => r) -> r
withMode @mode
    (if Bool
GetBool mode
c then f a b
t else f a b
e)
    ( forall (mode :: EvalModeTag) a r.
UnifiedSimpleMergeable mode a =>
(If (IsConMode mode) (() :: Constraint) (SimpleMergeable a) => r)
-> r
withBaseSimpleMergeable @mode @a ((If (IsConMode mode) (() :: Constraint) (SimpleMergeable a) =>
  f a b)
 -> f a b)
-> (If (IsConMode mode) (() :: Constraint) (SimpleMergeable a) =>
    f a b)
-> f a b
forall a b. (a -> b) -> a -> b
$
        forall (mode :: EvalModeTag) a r.
UnifiedSimpleMergeable mode a =>
(If (IsConMode mode) (() :: Constraint) (SimpleMergeable a) => r)
-> r
withBaseSimpleMergeable @mode @b ((If (IsConMode mode) (() :: Constraint) (SimpleMergeable b) =>
  f a b)
 -> f a b)
-> (If (IsConMode mode) (() :: Constraint) (SimpleMergeable b) =>
    f a b)
-> f a b
forall a b. (a -> b) -> a -> b
$
          forall (mode :: EvalModeTag) (f :: * -> * -> *) r.
UnifiedSimpleMergeable2 mode f =>
(If (IsConMode mode) (() :: Constraint) (SimpleMergeable2 f) => r)
-> r
withBaseSimpleMergeable2 @mode @f ((If (IsConMode mode) (() :: Constraint) (SimpleMergeable2 f) =>
  f a b)
 -> f a b)
-> (If (IsConMode mode) (() :: Constraint) (SimpleMergeable2 f) =>
    f a b)
-> f a b
forall a b. (a -> b) -> a -> b
$
            SymBool -> f a b -> f a b -> f a b
forall (u :: * -> * -> *) a b.
(SimpleMergeable2 u, SimpleMergeable a, SimpleMergeable b) =>
SymBool -> u a b -> u a b -> u a b
Grisette.Internal.Core.Data.Class.SimpleMergeable.mrgIte2 SymBool
GetBool mode
c f a b
t f a b
e
    )

-- | Unified `Grisette.liftMrgIte2`.
liftMrgIte2 ::
  forall mode f a b.
  (UnifiedSimpleMergeable2 mode f) =>
  (GetBool mode -> a -> a -> a) ->
  (GetBool mode -> b -> b -> b) ->
  GetBool mode ->
  f a b ->
  f a b ->
  f a b
liftMrgIte2 :: forall (mode :: EvalModeTag) (f :: * -> * -> *) a b.
UnifiedSimpleMergeable2 mode f =>
(GetBool mode -> a -> a -> a)
-> (GetBool mode -> b -> b -> b)
-> GetBool mode
-> f a b
-> f a b
-> f a b
liftMrgIte2 GetBool mode -> a -> a -> a
f GetBool mode -> b -> b -> b
g GetBool mode
c f a b
t f a b
e =
  forall (mode :: EvalModeTag) r.
DecideEvalMode mode =>
((mode ~ 'C) => r) -> ((mode ~ 'S) => r) -> r
withMode @mode
    (if Bool
GetBool mode
c then f a b
t else f a b
e)
    ( forall (mode :: EvalModeTag) (f :: * -> * -> *) r.
UnifiedSimpleMergeable2 mode f =>
(If (IsConMode mode) (() :: Constraint) (SimpleMergeable2 f) => r)
-> r
withBaseSimpleMergeable2 @mode @f ((If (IsConMode mode) (() :: Constraint) (SimpleMergeable2 f) =>
  f a b)
 -> f a b)
-> (If (IsConMode mode) (() :: Constraint) (SimpleMergeable2 f) =>
    f a b)
-> f a b
forall a b. (a -> b) -> a -> b
$
        (SymBool -> a -> a -> a)
-> (SymBool -> b -> b -> b) -> SymBool -> f a b -> f a b -> f a b
forall a b.
(SymBool -> a -> a -> a)
-> (SymBool -> b -> b -> b) -> SymBool -> f a b -> f a b -> f a b
forall (u :: * -> * -> *) a b.
SimpleMergeable2 u =>
(SymBool -> a -> a -> a)
-> (SymBool -> b -> b -> b) -> SymBool -> u a b -> u a b -> u a b
Grisette.Internal.Core.Data.Class.SimpleMergeable.liftMrgIte2 SymBool -> a -> a -> a
GetBool mode -> a -> a -> a
f SymBool -> b -> b -> b
GetBool mode -> b -> b -> b
g SymBool
GetBool mode
c f a b
t f a b
e
    )

instance
  {-# INCOHERENT #-}
  ( DecideEvalMode mode,
    TryMerge m,
    If (IsConMode mode) ((TryMerge m) :: Constraint) (SymBranching m)
  ) =>
  UnifiedBranching mode m
  where
  withBaseBranching :: forall r.
(If (IsConMode mode) (TryMerge m) (SymBranching m) => r) -> r
withBaseBranching If (IsConMode mode) (TryMerge m) (SymBranching m) => r
r = r
If (IsConMode mode) (TryMerge m) (SymBranching m) => r
r
  {-# INLINE withBaseBranching #-}

instance
  {-# INCOHERENT #-}
  ( DecideEvalMode mode,
    Mergeable m,
    If (IsConMode mode) (() :: Constraint) (SimpleMergeable m)
  ) =>
  UnifiedSimpleMergeable mode m
  where
  withBaseSimpleMergeable :: forall r.
(If (IsConMode mode) (() :: Constraint) (SimpleMergeable m) => r)
-> r
withBaseSimpleMergeable If (IsConMode mode) (() :: Constraint) (SimpleMergeable m) => r
r = r
If (IsConMode mode) (() :: Constraint) (SimpleMergeable m) => r
r
  {-# INLINE withBaseSimpleMergeable #-}

instance
  {-# INCOHERENT #-}
  ( DecideEvalMode mode,
    If (IsConMode mode) (() :: Constraint) (SimpleMergeable1 m)
  ) =>
  UnifiedSimpleMergeable1 mode m
  where
  withBaseSimpleMergeable1 :: forall r.
(If (IsConMode mode) (() :: Constraint) (SimpleMergeable1 m) => r)
-> r
withBaseSimpleMergeable1 If (IsConMode mode) (() :: Constraint) (SimpleMergeable1 m) => r
r = r
If (IsConMode mode) (() :: Constraint) (SimpleMergeable1 m) => r
r
  {-# INLINE withBaseSimpleMergeable1 #-}

instance
  {-# INCOHERENT #-}
  ( DecideEvalMode mode,
    If (IsConMode mode) (() :: Constraint) (SimpleMergeable2 m)
  ) =>
  UnifiedSimpleMergeable2 mode m
  where
  withBaseSimpleMergeable2 :: forall r.
(If (IsConMode mode) (() :: Constraint) (SimpleMergeable2 m) => r)
-> r
withBaseSimpleMergeable2 If (IsConMode mode) (() :: Constraint) (SimpleMergeable2 m) => r
r = r
If (IsConMode mode) (() :: Constraint) (SimpleMergeable2 m) => r
r
  {-# INLINE withBaseSimpleMergeable2 #-}

derive
  [ ''(,),
    ''(,,),
    ''(,,,),
    ''(,,,,),
    ''(,,,,,),
    ''(,,,,,,),
    ''(,,,,,,,),
    ''(,,,,,,,,),
    ''(,,,,,,,,,),
    ''(,,,,,,,,,,),
    ''(,,,,,,,,,,,),
    ''(,,,,,,,,,,,,),
    ''(,,,,,,,,,,,,,),
    ''(,,,,,,,,,,,,,,)
  ]
  [ ''UnifiedSimpleMergeable,
    ''UnifiedSimpleMergeable1,
    ''UnifiedSimpleMergeable2
  ]

derive
  [''Identity]
  [''UnifiedSimpleMergeable, ''UnifiedSimpleMergeable1]

derive
  [''(), ''AssertionError]
  [''UnifiedSimpleMergeable]

instance
  (UnifiedSimpleMergeable mode b) =>
  UnifiedSimpleMergeable mode (a -> b)
  where
  withBaseSimpleMergeable :: forall r.
(If
   (IsConMode mode) (() :: Constraint) (SimpleMergeable (a -> b)) =>
 r)
-> r
withBaseSimpleMergeable If
  (IsConMode mode) (() :: Constraint) (SimpleMergeable (a -> b)) =>
r
r =
    forall (mode :: EvalModeTag) r.
DecideEvalMode mode =>
((mode ~ 'C) => r) -> ((mode ~ 'S) => r) -> r
withMode @mode
      (forall (mode :: EvalModeTag) a r.
UnifiedSimpleMergeable mode a =>
(If (IsConMode mode) (() :: Constraint) (SimpleMergeable a) => r)
-> r
withBaseSimpleMergeable @mode @b r
If (IsConMode mode) (() :: Constraint) (SimpleMergeable b) => r
If
  (IsConMode mode) (() :: Constraint) (SimpleMergeable (a -> b)) =>
r
r)
      (forall (mode :: EvalModeTag) a r.
UnifiedSimpleMergeable mode a =>
(If (IsConMode mode) (() :: Constraint) (SimpleMergeable a) => r)
-> r
withBaseSimpleMergeable @mode @b r
If (IsConMode mode) (() :: Constraint) (SimpleMergeable b) => r
If
  (IsConMode mode) (() :: Constraint) (SimpleMergeable (a -> b)) =>
r
r)
  {-# INLINE withBaseSimpleMergeable #-}

instance (DecideEvalMode mode) => UnifiedSimpleMergeable1 mode ((->) a) where
  withBaseSimpleMergeable1 :: forall r.
(If
   (IsConMode mode) (() :: Constraint) (SimpleMergeable1 ((->) a)) =>
 r)
-> r
withBaseSimpleMergeable1 If
  (IsConMode mode) (() :: Constraint) (SimpleMergeable1 ((->) a)) =>
r
r = forall (mode :: EvalModeTag) r.
DecideEvalMode mode =>
((mode ~ 'C) => r) -> ((mode ~ 'S) => r) -> r
withMode @mode r
(mode ~ 'C) => r
If
  (IsConMode mode) (() :: Constraint) (SimpleMergeable1 ((->) a)) =>
r
r r
(mode ~ 'S) => r
If
  (IsConMode mode) (() :: Constraint) (SimpleMergeable1 ((->) a)) =>
r
r
  {-# INLINE withBaseSimpleMergeable1 #-}

instance (DecideEvalMode mode) => UnifiedSimpleMergeable2 mode (->) where
  withBaseSimpleMergeable2 :: forall r.
(If (IsConMode mode) (() :: Constraint) (SimpleMergeable2 (->)) =>
 r)
-> r
withBaseSimpleMergeable2 If (IsConMode mode) (() :: Constraint) (SimpleMergeable2 (->)) => r
r = forall (mode :: EvalModeTag) r.
DecideEvalMode mode =>
((mode ~ 'C) => r) -> ((mode ~ 'S) => r) -> r
withMode @mode r
(mode ~ 'C) => r
If (IsConMode mode) (() :: Constraint) (SimpleMergeable2 (->)) => r
r r
(mode ~ 'S) => r
If (IsConMode mode) (() :: Constraint) (SimpleMergeable2 (->)) => r
r
  {-# INLINE withBaseSimpleMergeable2 #-}

instance
  (UnifiedBranching mode m, Mergeable a, Mergeable1 m) =>
  UnifiedSimpleMergeable mode (FreshT m a)
  where
  withBaseSimpleMergeable :: forall r.
(If
   (IsConMode mode)
   (() :: Constraint)
   (SimpleMergeable (FreshT m a)) =>
 r)
-> r
withBaseSimpleMergeable If
  (IsConMode mode)
  (() :: Constraint)
  (SimpleMergeable (FreshT m a)) =>
r
r =
    forall (mode :: EvalModeTag) r.
DecideEvalMode mode =>
((mode ~ 'C) => r) -> ((mode ~ 'S) => r) -> r
withMode @mode
      (forall (mode :: EvalModeTag) (m :: * -> *) r.
UnifiedBranching mode m =>
(If (IsConMode mode) (TryMerge m) (SymBranching m) => r) -> r
withBaseBranching @mode @m r
If
  (IsConMode mode)
  (() :: Constraint)
  (SimpleMergeable (FreshT m a)) =>
r
If (IsConMode mode) (TryMerge m) (SymBranching m) => r
r)
      (forall (mode :: EvalModeTag) (m :: * -> *) r.
UnifiedBranching mode m =>
(If (IsConMode mode) (TryMerge m) (SymBranching m) => r) -> r
withBaseBranching @mode @m r
If
  (IsConMode mode)
  (() :: Constraint)
  (SimpleMergeable (FreshT m a)) =>
r
If (IsConMode mode) (TryMerge m) (SymBranching m) => r
r)
  {-# INLINE withBaseSimpleMergeable #-}

instance
  (UnifiedBranching mode m) =>
  UnifiedSimpleMergeable1 mode (FreshT m)
  where
  withBaseSimpleMergeable1 :: forall r.
(If
   (IsConMode mode)
   (() :: Constraint)
   (SimpleMergeable1 (FreshT m)) =>
 r)
-> r
withBaseSimpleMergeable1 If
  (IsConMode mode)
  (() :: Constraint)
  (SimpleMergeable1 (FreshT m)) =>
r
r =
    forall (mode :: EvalModeTag) r.
DecideEvalMode mode =>
((mode ~ 'C) => r) -> ((mode ~ 'S) => r) -> r
withMode @mode
      (forall (mode :: EvalModeTag) (m :: * -> *) r.
UnifiedBranching mode m =>
(If (IsConMode mode) (TryMerge m) (SymBranching m) => r) -> r
withBaseBranching @mode @m r
If
  (IsConMode mode)
  (() :: Constraint)
  (SimpleMergeable1 (FreshT m)) =>
r
If (IsConMode mode) (TryMerge m) (SymBranching m) => r
r)
      (forall (mode :: EvalModeTag) (m :: * -> *) r.
UnifiedBranching mode m =>
(If (IsConMode mode) (TryMerge m) (SymBranching m) => r) -> r
withBaseBranching @mode @m r
If
  (IsConMode mode)
  (() :: Constraint)
  (SimpleMergeable1 (FreshT m)) =>
r
If (IsConMode mode) (TryMerge m) (SymBranching m) => r
r)
  {-# INLINE withBaseSimpleMergeable1 #-}

instance
  (UnifiedBranching mode m) =>
  UnifiedBranching mode (FreshT m)
  where
  withBaseBranching :: forall r.
(If
   (IsConMode mode) (TryMerge (FreshT m)) (SymBranching (FreshT m)) =>
 r)
-> r
withBaseBranching If
  (IsConMode mode) (TryMerge (FreshT m)) (SymBranching (FreshT m)) =>
r
r =
    forall (mode :: EvalModeTag) r.
DecideEvalMode mode =>
((mode ~ 'C) => r) -> ((mode ~ 'S) => r) -> r
withMode @mode
      (forall (mode :: EvalModeTag) (m :: * -> *) r.
UnifiedBranching mode m =>
(If (IsConMode mode) (TryMerge m) (SymBranching m) => r) -> r
withBaseBranching @mode @m r
If (IsConMode mode) (TryMerge m) (SymBranching m) => r
If
  (IsConMode mode) (TryMerge (FreshT m)) (SymBranching (FreshT m)) =>
r
r)
      (forall (mode :: EvalModeTag) (m :: * -> *) r.
UnifiedBranching mode m =>
(If (IsConMode mode) (TryMerge m) (SymBranching m) => r) -> r
withBaseBranching @mode @m r
If (IsConMode mode) (TryMerge m) (SymBranching m) => r
If
  (IsConMode mode) (TryMerge (FreshT m)) (SymBranching (FreshT m)) =>
r
r)
  {-# INLINE withBaseBranching #-}

instance
  (UnifiedBranching mode m, Mergeable a, Mergeable1 m) =>
  UnifiedSimpleMergeable mode (MaybeT m a)
  where
  withBaseSimpleMergeable :: forall r.
(If
   (IsConMode mode)
   (() :: Constraint)
   (SimpleMergeable (MaybeT m a)) =>
 r)
-> r
withBaseSimpleMergeable If
  (IsConMode mode)
  (() :: Constraint)
  (SimpleMergeable (MaybeT m a)) =>
r
r =
    forall (mode :: EvalModeTag) r.
DecideEvalMode mode =>
((mode ~ 'C) => r) -> ((mode ~ 'S) => r) -> r
withMode @mode
      (forall (mode :: EvalModeTag) (m :: * -> *) r.
UnifiedBranching mode m =>
(If (IsConMode mode) (TryMerge m) (SymBranching m) => r) -> r
withBaseBranching @mode @m r
If
  (IsConMode mode)
  (() :: Constraint)
  (SimpleMergeable (MaybeT m a)) =>
r
If (IsConMode mode) (TryMerge m) (SymBranching m) => r
r)
      (forall (mode :: EvalModeTag) (m :: * -> *) r.
UnifiedBranching mode m =>
(If (IsConMode mode) (TryMerge m) (SymBranching m) => r) -> r
withBaseBranching @mode @m r
If
  (IsConMode mode)
  (() :: Constraint)
  (SimpleMergeable (MaybeT m a)) =>
r
If (IsConMode mode) (TryMerge m) (SymBranching m) => r
r)
  {-# INLINE withBaseSimpleMergeable #-}

instance
  (UnifiedBranching mode m) =>
  UnifiedSimpleMergeable1 mode (MaybeT m)
  where
  withBaseSimpleMergeable1 :: forall r.
(If
   (IsConMode mode)
   (() :: Constraint)
   (SimpleMergeable1 (MaybeT m)) =>
 r)
-> r
withBaseSimpleMergeable1 If
  (IsConMode mode)
  (() :: Constraint)
  (SimpleMergeable1 (MaybeT m)) =>
r
r =
    forall (mode :: EvalModeTag) r.
DecideEvalMode mode =>
((mode ~ 'C) => r) -> ((mode ~ 'S) => r) -> r
withMode @mode
      (forall (mode :: EvalModeTag) (m :: * -> *) r.
UnifiedBranching mode m =>
(If (IsConMode mode) (TryMerge m) (SymBranching m) => r) -> r
withBaseBranching @mode @m r
If
  (IsConMode mode)
  (() :: Constraint)
  (SimpleMergeable1 (MaybeT m)) =>
r
If (IsConMode mode) (TryMerge m) (SymBranching m) => r
r)
      (forall (mode :: EvalModeTag) (m :: * -> *) r.
UnifiedBranching mode m =>
(If (IsConMode mode) (TryMerge m) (SymBranching m) => r) -> r
withBaseBranching @mode @m r
If
  (IsConMode mode)
  (() :: Constraint)
  (SimpleMergeable1 (MaybeT m)) =>
r
If (IsConMode mode) (TryMerge m) (SymBranching m) => r
r)
  {-# INLINE withBaseSimpleMergeable1 #-}

instance
  (UnifiedBranching mode m) =>
  UnifiedBranching mode (MaybeT m)
  where
  withBaseBranching :: forall r.
(If
   (IsConMode mode) (TryMerge (MaybeT m)) (SymBranching (MaybeT m)) =>
 r)
-> r
withBaseBranching If
  (IsConMode mode) (TryMerge (MaybeT m)) (SymBranching (MaybeT m)) =>
r
r =
    forall (mode :: EvalModeTag) r.
DecideEvalMode mode =>
((mode ~ 'C) => r) -> ((mode ~ 'S) => r) -> r
withMode @mode
      (forall (mode :: EvalModeTag) (m :: * -> *) r.
UnifiedBranching mode m =>
(If (IsConMode mode) (TryMerge m) (SymBranching m) => r) -> r
withBaseBranching @mode @m r
If (IsConMode mode) (TryMerge m) (SymBranching m) => r
If
  (IsConMode mode) (TryMerge (MaybeT m)) (SymBranching (MaybeT m)) =>
r
r)
      (forall (mode :: EvalModeTag) (m :: * -> *) r.
UnifiedBranching mode m =>
(If (IsConMode mode) (TryMerge m) (SymBranching m) => r) -> r
withBaseBranching @mode @m r
If (IsConMode mode) (TryMerge m) (SymBranching m) => r
If
  (IsConMode mode) (TryMerge (MaybeT m)) (SymBranching (MaybeT m)) =>
r
r)
  {-# INLINE withBaseBranching #-}

instance
  (UnifiedBranching mode m, Mergeable a, Mergeable1 m) =>
  UnifiedSimpleMergeable mode (IdentityT m a)
  where
  withBaseSimpleMergeable :: forall r.
(If
   (IsConMode mode)
   (() :: Constraint)
   (SimpleMergeable (IdentityT m a)) =>
 r)
-> r
withBaseSimpleMergeable If
  (IsConMode mode)
  (() :: Constraint)
  (SimpleMergeable (IdentityT m a)) =>
r
r =
    forall (mode :: EvalModeTag) r.
DecideEvalMode mode =>
((mode ~ 'C) => r) -> ((mode ~ 'S) => r) -> r
withMode @mode
      (forall (mode :: EvalModeTag) (m :: * -> *) r.
UnifiedBranching mode m =>
(If (IsConMode mode) (TryMerge m) (SymBranching m) => r) -> r
withBaseBranching @mode @m r
If
  (IsConMode mode)
  (() :: Constraint)
  (SimpleMergeable (IdentityT m a)) =>
r
If (IsConMode mode) (TryMerge m) (SymBranching m) => r
r)
      (forall (mode :: EvalModeTag) (m :: * -> *) r.
UnifiedBranching mode m =>
(If (IsConMode mode) (TryMerge m) (SymBranching m) => r) -> r
withBaseBranching @mode @m r
If
  (IsConMode mode)
  (() :: Constraint)
  (SimpleMergeable (IdentityT m a)) =>
r
If (IsConMode mode) (TryMerge m) (SymBranching m) => r
r)
  {-# INLINE withBaseSimpleMergeable #-}

instance
  (UnifiedBranching mode m) =>
  UnifiedSimpleMergeable1 mode (IdentityT m)
  where
  withBaseSimpleMergeable1 :: forall r.
(If
   (IsConMode mode)
   (() :: Constraint)
   (SimpleMergeable1 (IdentityT m)) =>
 r)
-> r
withBaseSimpleMergeable1 If
  (IsConMode mode)
  (() :: Constraint)
  (SimpleMergeable1 (IdentityT m)) =>
r
r =
    forall (mode :: EvalModeTag) r.
DecideEvalMode mode =>
((mode ~ 'C) => r) -> ((mode ~ 'S) => r) -> r
withMode @mode
      (forall (mode :: EvalModeTag) (m :: * -> *) r.
UnifiedBranching mode m =>
(If (IsConMode mode) (TryMerge m) (SymBranching m) => r) -> r
withBaseBranching @mode @m r
If
  (IsConMode mode)
  (() :: Constraint)
  (SimpleMergeable1 (IdentityT m)) =>
r
If (IsConMode mode) (TryMerge m) (SymBranching m) => r
r)
      (forall (mode :: EvalModeTag) (m :: * -> *) r.
UnifiedBranching mode m =>
(If (IsConMode mode) (TryMerge m) (SymBranching m) => r) -> r
withBaseBranching @mode @m r
If
  (IsConMode mode)
  (() :: Constraint)
  (SimpleMergeable1 (IdentityT m)) =>
r
If (IsConMode mode) (TryMerge m) (SymBranching m) => r
r)
  {-# INLINE withBaseSimpleMergeable1 #-}

instance
  (UnifiedBranching mode m) =>
  UnifiedBranching mode (IdentityT m)
  where
  withBaseBranching :: forall r.
(If
   (IsConMode mode)
   (TryMerge (IdentityT m))
   (SymBranching (IdentityT m)) =>
 r)
-> r
withBaseBranching If
  (IsConMode mode)
  (TryMerge (IdentityT m))
  (SymBranching (IdentityT m)) =>
r
r =
    forall (mode :: EvalModeTag) r.
DecideEvalMode mode =>
((mode ~ 'C) => r) -> ((mode ~ 'S) => r) -> r
withMode @mode
      (forall (mode :: EvalModeTag) (m :: * -> *) r.
UnifiedBranching mode m =>
(If (IsConMode mode) (TryMerge m) (SymBranching m) => r) -> r
withBaseBranching @mode @m r
If (IsConMode mode) (TryMerge m) (SymBranching m) => r
If
  (IsConMode mode)
  (TryMerge (IdentityT m))
  (SymBranching (IdentityT m)) =>
r
r)
      (forall (mode :: EvalModeTag) (m :: * -> *) r.
UnifiedBranching mode m =>
(If (IsConMode mode) (TryMerge m) (SymBranching m) => r) -> r
withBaseBranching @mode @m r
If (IsConMode mode) (TryMerge m) (SymBranching m) => r
If
  (IsConMode mode)
  (TryMerge (IdentityT m))
  (SymBranching (IdentityT m)) =>
r
r)
  {-# INLINE withBaseBranching #-}

instance
  (UnifiedBranching mode m, Mergeable a, Mergeable1 m) =>
  UnifiedSimpleMergeable mode (ReaderT r m a)
  where
  withBaseSimpleMergeable :: forall r.
(If
   (IsConMode mode)
   (() :: Constraint)
   (SimpleMergeable (ReaderT r m a)) =>
 r)
-> r
withBaseSimpleMergeable If
  (IsConMode mode)
  (() :: Constraint)
  (SimpleMergeable (ReaderT r m a)) =>
r
r =
    forall (mode :: EvalModeTag) r.
DecideEvalMode mode =>
((mode ~ 'C) => r) -> ((mode ~ 'S) => r) -> r
withMode @mode
      (forall (mode :: EvalModeTag) (m :: * -> *) r.
UnifiedBranching mode m =>
(If (IsConMode mode) (TryMerge m) (SymBranching m) => r) -> r
withBaseBranching @mode @m r
If
  (IsConMode mode)
  (() :: Constraint)
  (SimpleMergeable (ReaderT r m a)) =>
r
If (IsConMode mode) (TryMerge m) (SymBranching m) => r
r)
      (forall (mode :: EvalModeTag) (m :: * -> *) r.
UnifiedBranching mode m =>
(If (IsConMode mode) (TryMerge m) (SymBranching m) => r) -> r
withBaseBranching @mode @m r
If
  (IsConMode mode)
  (() :: Constraint)
  (SimpleMergeable (ReaderT r m a)) =>
r
If (IsConMode mode) (TryMerge m) (SymBranching m) => r
r)
  {-# INLINE withBaseSimpleMergeable #-}

instance
  (UnifiedBranching mode m) =>
  UnifiedSimpleMergeable1 mode (ReaderT r m)
  where
  withBaseSimpleMergeable1 :: forall r.
(If
   (IsConMode mode)
   (() :: Constraint)
   (SimpleMergeable1 (ReaderT r m)) =>
 r)
-> r
withBaseSimpleMergeable1 If
  (IsConMode mode)
  (() :: Constraint)
  (SimpleMergeable1 (ReaderT r m)) =>
r
r =
    forall (mode :: EvalModeTag) r.
DecideEvalMode mode =>
((mode ~ 'C) => r) -> ((mode ~ 'S) => r) -> r
withMode @mode
      (forall (mode :: EvalModeTag) (m :: * -> *) r.
UnifiedBranching mode m =>
(If (IsConMode mode) (TryMerge m) (SymBranching m) => r) -> r
withBaseBranching @mode @m r
If
  (IsConMode mode)
  (() :: Constraint)
  (SimpleMergeable1 (ReaderT r m)) =>
r
If (IsConMode mode) (TryMerge m) (SymBranching m) => r
r)
      (forall (mode :: EvalModeTag) (m :: * -> *) r.
UnifiedBranching mode m =>
(If (IsConMode mode) (TryMerge m) (SymBranching m) => r) -> r
withBaseBranching @mode @m r
If
  (IsConMode mode)
  (() :: Constraint)
  (SimpleMergeable1 (ReaderT r m)) =>
r
If (IsConMode mode) (TryMerge m) (SymBranching m) => r
r)
  {-# INLINE withBaseSimpleMergeable1 #-}

instance
  (UnifiedBranching mode m) =>
  UnifiedBranching mode (ReaderT r m)
  where
  withBaseBranching :: forall r.
(If
   (IsConMode mode)
   (TryMerge (ReaderT r m))
   (SymBranching (ReaderT r m)) =>
 r)
-> r
withBaseBranching If
  (IsConMode mode)
  (TryMerge (ReaderT r m))
  (SymBranching (ReaderT r m)) =>
r
r =
    forall (mode :: EvalModeTag) r.
DecideEvalMode mode =>
((mode ~ 'C) => r) -> ((mode ~ 'S) => r) -> r
withMode @mode
      (forall (mode :: EvalModeTag) (m :: * -> *) r.
UnifiedBranching mode m =>
(If (IsConMode mode) (TryMerge m) (SymBranching m) => r) -> r
withBaseBranching @mode @m r
If (IsConMode mode) (TryMerge m) (SymBranching m) => r
If
  (IsConMode mode)
  (TryMerge (ReaderT r m))
  (SymBranching (ReaderT r m)) =>
r
r)
      (forall (mode :: EvalModeTag) (m :: * -> *) r.
UnifiedBranching mode m =>
(If (IsConMode mode) (TryMerge m) (SymBranching m) => r) -> r
withBaseBranching @mode @m r
If (IsConMode mode) (TryMerge m) (SymBranching m) => r
If
  (IsConMode mode)
  (TryMerge (ReaderT r m))
  (SymBranching (ReaderT r m)) =>
r
r)
  {-# INLINE withBaseBranching #-}

instance
  (UnifiedBranching mode m, Mergeable s, Mergeable a, Mergeable1 m) =>
  UnifiedSimpleMergeable mode (StateLazy.StateT s m a)
  where
  withBaseSimpleMergeable :: forall r.
(If
   (IsConMode mode)
   (() :: Constraint)
   (SimpleMergeable (StateT s m a)) =>
 r)
-> r
withBaseSimpleMergeable If
  (IsConMode mode)
  (() :: Constraint)
  (SimpleMergeable (StateT s m a)) =>
r
r =
    forall (mode :: EvalModeTag) r.
DecideEvalMode mode =>
((mode ~ 'C) => r) -> ((mode ~ 'S) => r) -> r
withMode @mode
      (forall (mode :: EvalModeTag) (m :: * -> *) r.
UnifiedBranching mode m =>
(If (IsConMode mode) (TryMerge m) (SymBranching m) => r) -> r
withBaseBranching @mode @m r
If
  (IsConMode mode)
  (() :: Constraint)
  (SimpleMergeable (StateT s m a)) =>
r
If (IsConMode mode) (TryMerge m) (SymBranching m) => r
r)
      (forall (mode :: EvalModeTag) (m :: * -> *) r.
UnifiedBranching mode m =>
(If (IsConMode mode) (TryMerge m) (SymBranching m) => r) -> r
withBaseBranching @mode @m r
If
  (IsConMode mode)
  (() :: Constraint)
  (SimpleMergeable (StateT s m a)) =>
r
If (IsConMode mode) (TryMerge m) (SymBranching m) => r
r)
  {-# INLINE withBaseSimpleMergeable #-}

instance
  (UnifiedBranching mode m, Mergeable s) =>
  UnifiedSimpleMergeable1 mode (StateLazy.StateT s m)
  where
  withBaseSimpleMergeable1 :: forall r.
(If
   (IsConMode mode)
   (() :: Constraint)
   (SimpleMergeable1 (StateT s m)) =>
 r)
-> r
withBaseSimpleMergeable1 If
  (IsConMode mode)
  (() :: Constraint)
  (SimpleMergeable1 (StateT s m)) =>
r
r =
    forall (mode :: EvalModeTag) r.
DecideEvalMode mode =>
((mode ~ 'C) => r) -> ((mode ~ 'S) => r) -> r
withMode @mode
      (forall (mode :: EvalModeTag) (m :: * -> *) r.
UnifiedBranching mode m =>
(If (IsConMode mode) (TryMerge m) (SymBranching m) => r) -> r
withBaseBranching @mode @m r
If
  (IsConMode mode)
  (() :: Constraint)
  (SimpleMergeable1 (StateT s m)) =>
r
If (IsConMode mode) (TryMerge m) (SymBranching m) => r
r)
      (forall (mode :: EvalModeTag) (m :: * -> *) r.
UnifiedBranching mode m =>
(If (IsConMode mode) (TryMerge m) (SymBranching m) => r) -> r
withBaseBranching @mode @m r
If
  (IsConMode mode)
  (() :: Constraint)
  (SimpleMergeable1 (StateT s m)) =>
r
If (IsConMode mode) (TryMerge m) (SymBranching m) => r
r)
  {-# INLINE withBaseSimpleMergeable1 #-}

instance
  (UnifiedBranching mode m, Mergeable s) =>
  UnifiedBranching mode (StateLazy.StateT s m)
  where
  withBaseBranching :: forall r.
(If
   (IsConMode mode)
   (TryMerge (StateT s m))
   (SymBranching (StateT s m)) =>
 r)
-> r
withBaseBranching If
  (IsConMode mode)
  (TryMerge (StateT s m))
  (SymBranching (StateT s m)) =>
r
r =
    forall (mode :: EvalModeTag) r.
DecideEvalMode mode =>
((mode ~ 'C) => r) -> ((mode ~ 'S) => r) -> r
withMode @mode
      (forall (mode :: EvalModeTag) (m :: * -> *) r.
UnifiedBranching mode m =>
(If (IsConMode mode) (TryMerge m) (SymBranching m) => r) -> r
withBaseBranching @mode @m r
If (IsConMode mode) (TryMerge m) (SymBranching m) => r
If
  (IsConMode mode)
  (TryMerge (StateT s m))
  (SymBranching (StateT s m)) =>
r
r)
      (forall (mode :: EvalModeTag) (m :: * -> *) r.
UnifiedBranching mode m =>
(If (IsConMode mode) (TryMerge m) (SymBranching m) => r) -> r
withBaseBranching @mode @m r
If (IsConMode mode) (TryMerge m) (SymBranching m) => r
If
  (IsConMode mode)
  (TryMerge (StateT s m))
  (SymBranching (StateT s m)) =>
r
r)
  {-# INLINE withBaseBranching #-}

instance
  (UnifiedBranching mode m, Mergeable s, Mergeable a, Mergeable1 m) =>
  UnifiedSimpleMergeable mode (StateStrict.StateT s m a)
  where
  withBaseSimpleMergeable :: forall r.
(If
   (IsConMode mode)
   (() :: Constraint)
   (SimpleMergeable (StateT s m a)) =>
 r)
-> r
withBaseSimpleMergeable If
  (IsConMode mode)
  (() :: Constraint)
  (SimpleMergeable (StateT s m a)) =>
r
r =
    forall (mode :: EvalModeTag) r.
DecideEvalMode mode =>
((mode ~ 'C) => r) -> ((mode ~ 'S) => r) -> r
withMode @mode
      (forall (mode :: EvalModeTag) (m :: * -> *) r.
UnifiedBranching mode m =>
(If (IsConMode mode) (TryMerge m) (SymBranching m) => r) -> r
withBaseBranching @mode @m r
If
  (IsConMode mode)
  (() :: Constraint)
  (SimpleMergeable (StateT s m a)) =>
r
If (IsConMode mode) (TryMerge m) (SymBranching m) => r
r)
      (forall (mode :: EvalModeTag) (m :: * -> *) r.
UnifiedBranching mode m =>
(If (IsConMode mode) (TryMerge m) (SymBranching m) => r) -> r
withBaseBranching @mode @m r
If
  (IsConMode mode)
  (() :: Constraint)
  (SimpleMergeable (StateT s m a)) =>
r
If (IsConMode mode) (TryMerge m) (SymBranching m) => r
r)
  {-# INLINE withBaseSimpleMergeable #-}

instance
  (UnifiedBranching mode m, Mergeable s) =>
  UnifiedSimpleMergeable1 mode (StateStrict.StateT s m)
  where
  withBaseSimpleMergeable1 :: forall r.
(If
   (IsConMode mode)
   (() :: Constraint)
   (SimpleMergeable1 (StateT s m)) =>
 r)
-> r
withBaseSimpleMergeable1 If
  (IsConMode mode)
  (() :: Constraint)
  (SimpleMergeable1 (StateT s m)) =>
r
r =
    forall (mode :: EvalModeTag) r.
DecideEvalMode mode =>
((mode ~ 'C) => r) -> ((mode ~ 'S) => r) -> r
withMode @mode
      (forall (mode :: EvalModeTag) (m :: * -> *) r.
UnifiedBranching mode m =>
(If (IsConMode mode) (TryMerge m) (SymBranching m) => r) -> r
withBaseBranching @mode @m r
If
  (IsConMode mode)
  (() :: Constraint)
  (SimpleMergeable1 (StateT s m)) =>
r
If (IsConMode mode) (TryMerge m) (SymBranching m) => r
r)
      (forall (mode :: EvalModeTag) (m :: * -> *) r.
UnifiedBranching mode m =>
(If (IsConMode mode) (TryMerge m) (SymBranching m) => r) -> r
withBaseBranching @mode @m r
If
  (IsConMode mode)
  (() :: Constraint)
  (SimpleMergeable1 (StateT s m)) =>
r
If (IsConMode mode) (TryMerge m) (SymBranching m) => r
r)
  {-# INLINE withBaseSimpleMergeable1 #-}

instance
  (UnifiedBranching mode m, Mergeable s) =>
  UnifiedBranching mode (StateStrict.StateT s m)
  where
  withBaseBranching :: forall r.
(If
   (IsConMode mode)
   (TryMerge (StateT s m))
   (SymBranching (StateT s m)) =>
 r)
-> r
withBaseBranching If
  (IsConMode mode)
  (TryMerge (StateT s m))
  (SymBranching (StateT s m)) =>
r
r =
    forall (mode :: EvalModeTag) r.
DecideEvalMode mode =>
((mode ~ 'C) => r) -> ((mode ~ 'S) => r) -> r
withMode @mode
      (forall (mode :: EvalModeTag) (m :: * -> *) r.
UnifiedBranching mode m =>
(If (IsConMode mode) (TryMerge m) (SymBranching m) => r) -> r
withBaseBranching @mode @m r
If (IsConMode mode) (TryMerge m) (SymBranching m) => r
If
  (IsConMode mode)
  (TryMerge (StateT s m))
  (SymBranching (StateT s m)) =>
r
r)
      (forall (mode :: EvalModeTag) (m :: * -> *) r.
UnifiedBranching mode m =>
(If (IsConMode mode) (TryMerge m) (SymBranching m) => r) -> r
withBaseBranching @mode @m r
If (IsConMode mode) (TryMerge m) (SymBranching m) => r
If
  (IsConMode mode)
  (TryMerge (StateT s m))
  (SymBranching (StateT s m)) =>
r
r)
  {-# INLINE withBaseBranching #-}

instance
  (UnifiedBranching mode m, Mergeable w, Mergeable a, Monoid w, Mergeable1 m) =>
  UnifiedSimpleMergeable mode (WriterLazy.WriterT w m a)
  where
  withBaseSimpleMergeable :: forall r.
(If
   (IsConMode mode)
   (() :: Constraint)
   (SimpleMergeable (WriterT w m a)) =>
 r)
-> r
withBaseSimpleMergeable If
  (IsConMode mode)
  (() :: Constraint)
  (SimpleMergeable (WriterT w m a)) =>
r
r =
    forall (mode :: EvalModeTag) r.
DecideEvalMode mode =>
((mode ~ 'C) => r) -> ((mode ~ 'S) => r) -> r
withMode @mode
      (forall (mode :: EvalModeTag) (m :: * -> *) r.
UnifiedBranching mode m =>
(If (IsConMode mode) (TryMerge m) (SymBranching m) => r) -> r
withBaseBranching @mode @m r
If
  (IsConMode mode)
  (() :: Constraint)
  (SimpleMergeable (WriterT w m a)) =>
r
If (IsConMode mode) (TryMerge m) (SymBranching m) => r
r)
      (forall (mode :: EvalModeTag) (m :: * -> *) r.
UnifiedBranching mode m =>
(If (IsConMode mode) (TryMerge m) (SymBranching m) => r) -> r
withBaseBranching @mode @m r
If
  (IsConMode mode)
  (() :: Constraint)
  (SimpleMergeable (WriterT w m a)) =>
r
If (IsConMode mode) (TryMerge m) (SymBranching m) => r
r)
  {-# INLINE withBaseSimpleMergeable #-}

instance
  (UnifiedBranching mode m, Mergeable w, Monoid w, Mergeable1 m) =>
  UnifiedSimpleMergeable1 mode (WriterLazy.WriterT w m)
  where
  withBaseSimpleMergeable1 :: forall r.
(If
   (IsConMode mode)
   (() :: Constraint)
   (SimpleMergeable1 (WriterT w m)) =>
 r)
-> r
withBaseSimpleMergeable1 If
  (IsConMode mode)
  (() :: Constraint)
  (SimpleMergeable1 (WriterT w m)) =>
r
r =
    forall (mode :: EvalModeTag) r.
DecideEvalMode mode =>
((mode ~ 'C) => r) -> ((mode ~ 'S) => r) -> r
withMode @mode
      (forall (mode :: EvalModeTag) (m :: * -> *) r.
UnifiedBranching mode m =>
(If (IsConMode mode) (TryMerge m) (SymBranching m) => r) -> r
withBaseBranching @mode @m r
If
  (IsConMode mode)
  (() :: Constraint)
  (SimpleMergeable1 (WriterT w m)) =>
r
If (IsConMode mode) (TryMerge m) (SymBranching m) => r
r)
      (forall (mode :: EvalModeTag) (m :: * -> *) r.
UnifiedBranching mode m =>
(If (IsConMode mode) (TryMerge m) (SymBranching m) => r) -> r
withBaseBranching @mode @m r
If
  (IsConMode mode)
  (() :: Constraint)
  (SimpleMergeable1 (WriterT w m)) =>
r
If (IsConMode mode) (TryMerge m) (SymBranching m) => r
r)
  {-# INLINE withBaseSimpleMergeable1 #-}

instance
  (UnifiedBranching mode m, Monoid w, Mergeable w) =>
  UnifiedBranching mode (WriterLazy.WriterT w m)
  where
  withBaseBranching :: forall r.
(If
   (IsConMode mode)
   (TryMerge (WriterT w m))
   (SymBranching (WriterT w m)) =>
 r)
-> r
withBaseBranching If
  (IsConMode mode)
  (TryMerge (WriterT w m))
  (SymBranching (WriterT w m)) =>
r
r =
    forall (mode :: EvalModeTag) r.
DecideEvalMode mode =>
((mode ~ 'C) => r) -> ((mode ~ 'S) => r) -> r
withMode @mode
      (forall (mode :: EvalModeTag) (m :: * -> *) r.
UnifiedBranching mode m =>
(If (IsConMode mode) (TryMerge m) (SymBranching m) => r) -> r
withBaseBranching @mode @m r
If (IsConMode mode) (TryMerge m) (SymBranching m) => r
If
  (IsConMode mode)
  (TryMerge (WriterT w m))
  (SymBranching (WriterT w m)) =>
r
r)
      (forall (mode :: EvalModeTag) (m :: * -> *) r.
UnifiedBranching mode m =>
(If (IsConMode mode) (TryMerge m) (SymBranching m) => r) -> r
withBaseBranching @mode @m r
If (IsConMode mode) (TryMerge m) (SymBranching m) => r
If
  (IsConMode mode)
  (TryMerge (WriterT w m))
  (SymBranching (WriterT w m)) =>
r
r)
  {-# INLINE withBaseBranching #-}

instance
  (UnifiedBranching mode m, Mergeable w, Mergeable a, Monoid w, Mergeable1 m) =>
  UnifiedSimpleMergeable mode (WriterStrict.WriterT w m a)
  where
  withBaseSimpleMergeable :: forall r.
(If
   (IsConMode mode)
   (() :: Constraint)
   (SimpleMergeable (WriterT w m a)) =>
 r)
-> r
withBaseSimpleMergeable If
  (IsConMode mode)
  (() :: Constraint)
  (SimpleMergeable (WriterT w m a)) =>
r
r =
    forall (mode :: EvalModeTag) r.
DecideEvalMode mode =>
((mode ~ 'C) => r) -> ((mode ~ 'S) => r) -> r
withMode @mode
      (forall (mode :: EvalModeTag) (m :: * -> *) r.
UnifiedBranching mode m =>
(If (IsConMode mode) (TryMerge m) (SymBranching m) => r) -> r
withBaseBranching @mode @m r
If
  (IsConMode mode)
  (() :: Constraint)
  (SimpleMergeable (WriterT w m a)) =>
r
If (IsConMode mode) (TryMerge m) (SymBranching m) => r
r)
      (forall (mode :: EvalModeTag) (m :: * -> *) r.
UnifiedBranching mode m =>
(If (IsConMode mode) (TryMerge m) (SymBranching m) => r) -> r
withBaseBranching @mode @m r
If
  (IsConMode mode)
  (() :: Constraint)
  (SimpleMergeable (WriterT w m a)) =>
r
If (IsConMode mode) (TryMerge m) (SymBranching m) => r
r)
  {-# INLINE withBaseSimpleMergeable #-}

instance
  (UnifiedBranching mode m, Mergeable w, Monoid w, Mergeable1 m) =>
  UnifiedSimpleMergeable1 mode (WriterStrict.WriterT w m)
  where
  withBaseSimpleMergeable1 :: forall r.
(If
   (IsConMode mode)
   (() :: Constraint)
   (SimpleMergeable1 (WriterT w m)) =>
 r)
-> r
withBaseSimpleMergeable1 If
  (IsConMode mode)
  (() :: Constraint)
  (SimpleMergeable1 (WriterT w m)) =>
r
r =
    forall (mode :: EvalModeTag) r.
DecideEvalMode mode =>
((mode ~ 'C) => r) -> ((mode ~ 'S) => r) -> r
withMode @mode
      (forall (mode :: EvalModeTag) (m :: * -> *) r.
UnifiedBranching mode m =>
(If (IsConMode mode) (TryMerge m) (SymBranching m) => r) -> r
withBaseBranching @mode @m r
If
  (IsConMode mode)
  (() :: Constraint)
  (SimpleMergeable1 (WriterT w m)) =>
r
If (IsConMode mode) (TryMerge m) (SymBranching m) => r
r)
      (forall (mode :: EvalModeTag) (m :: * -> *) r.
UnifiedBranching mode m =>
(If (IsConMode mode) (TryMerge m) (SymBranching m) => r) -> r
withBaseBranching @mode @m r
If
  (IsConMode mode)
  (() :: Constraint)
  (SimpleMergeable1 (WriterT w m)) =>
r
If (IsConMode mode) (TryMerge m) (SymBranching m) => r
r)
  {-# INLINE withBaseSimpleMergeable1 #-}

instance
  (UnifiedBranching mode m, Monoid w, Mergeable w) =>
  UnifiedBranching mode (WriterStrict.WriterT w m)
  where
  withBaseBranching :: forall r.
(If
   (IsConMode mode)
   (TryMerge (WriterT w m))
   (SymBranching (WriterT w m)) =>
 r)
-> r
withBaseBranching If
  (IsConMode mode)
  (TryMerge (WriterT w m))
  (SymBranching (WriterT w m)) =>
r
r =
    forall (mode :: EvalModeTag) r.
DecideEvalMode mode =>
((mode ~ 'C) => r) -> ((mode ~ 'S) => r) -> r
withMode @mode
      (forall (mode :: EvalModeTag) (m :: * -> *) r.
UnifiedBranching mode m =>
(If (IsConMode mode) (TryMerge m) (SymBranching m) => r) -> r
withBaseBranching @mode @m r
If (IsConMode mode) (TryMerge m) (SymBranching m) => r
If
  (IsConMode mode)
  (TryMerge (WriterT w m))
  (SymBranching (WriterT w m)) =>
r
r)
      (forall (mode :: EvalModeTag) (m :: * -> *) r.
UnifiedBranching mode m =>
(If (IsConMode mode) (TryMerge m) (SymBranching m) => r) -> r
withBaseBranching @mode @m r
If (IsConMode mode) (TryMerge m) (SymBranching m) => r
If
  (IsConMode mode)
  (TryMerge (WriterT w m))
  (SymBranching (WriterT w m)) =>
r
r)
  {-# INLINE withBaseBranching #-}

instance
  (UnifiedBranching mode m, Mergeable e, Mergeable a, Mergeable1 m) =>
  UnifiedSimpleMergeable mode (ExceptT e m a)
  where
  withBaseSimpleMergeable :: forall r.
(If
   (IsConMode mode)
   (() :: Constraint)
   (SimpleMergeable (ExceptT e m a)) =>
 r)
-> r
withBaseSimpleMergeable If
  (IsConMode mode)
  (() :: Constraint)
  (SimpleMergeable (ExceptT e m a)) =>
r
r =
    forall (mode :: EvalModeTag) r.
DecideEvalMode mode =>
((mode ~ 'C) => r) -> ((mode ~ 'S) => r) -> r
withMode @mode
      (forall (mode :: EvalModeTag) (m :: * -> *) r.
UnifiedBranching mode m =>
(If (IsConMode mode) (TryMerge m) (SymBranching m) => r) -> r
withBaseBranching @mode @m r
If
  (IsConMode mode)
  (() :: Constraint)
  (SimpleMergeable (ExceptT e m a)) =>
r
If (IsConMode mode) (TryMerge m) (SymBranching m) => r
r)
      (forall (mode :: EvalModeTag) (m :: * -> *) r.
UnifiedBranching mode m =>
(If (IsConMode mode) (TryMerge m) (SymBranching m) => r) -> r
withBaseBranching @mode @m r
If
  (IsConMode mode)
  (() :: Constraint)
  (SimpleMergeable (ExceptT e m a)) =>
r
If (IsConMode mode) (TryMerge m) (SymBranching m) => r
r)
  {-# INLINE withBaseSimpleMergeable #-}

instance
  (UnifiedBranching mode m, Mergeable e, Mergeable1 m) =>
  UnifiedSimpleMergeable1 mode (ExceptT e m)
  where
  withBaseSimpleMergeable1 :: forall r.
(If
   (IsConMode mode)
   (() :: Constraint)
   (SimpleMergeable1 (ExceptT e m)) =>
 r)
-> r
withBaseSimpleMergeable1 If
  (IsConMode mode)
  (() :: Constraint)
  (SimpleMergeable1 (ExceptT e m)) =>
r
r =
    forall (mode :: EvalModeTag) r.
DecideEvalMode mode =>
((mode ~ 'C) => r) -> ((mode ~ 'S) => r) -> r
withMode @mode
      (forall (mode :: EvalModeTag) (m :: * -> *) r.
UnifiedBranching mode m =>
(If (IsConMode mode) (TryMerge m) (SymBranching m) => r) -> r
withBaseBranching @mode @m r
If
  (IsConMode mode)
  (() :: Constraint)
  (SimpleMergeable1 (ExceptT e m)) =>
r
If (IsConMode mode) (TryMerge m) (SymBranching m) => r
r)
      (forall (mode :: EvalModeTag) (m :: * -> *) r.
UnifiedBranching mode m =>
(If (IsConMode mode) (TryMerge m) (SymBranching m) => r) -> r
withBaseBranching @mode @m r
If
  (IsConMode mode)
  (() :: Constraint)
  (SimpleMergeable1 (ExceptT e m)) =>
r
If (IsConMode mode) (TryMerge m) (SymBranching m) => r
r)
  {-# INLINE withBaseSimpleMergeable1 #-}

instance
  (UnifiedBranching mode m, Mergeable e) =>
  UnifiedBranching mode (ExceptT e m)
  where
  withBaseBranching :: forall r.
(If
   (IsConMode mode)
   (TryMerge (ExceptT e m))
   (SymBranching (ExceptT e m)) =>
 r)
-> r
withBaseBranching If
  (IsConMode mode)
  (TryMerge (ExceptT e m))
  (SymBranching (ExceptT e m)) =>
r
r =
    forall (mode :: EvalModeTag) r.
DecideEvalMode mode =>
((mode ~ 'C) => r) -> ((mode ~ 'S) => r) -> r
withMode @mode
      (forall (mode :: EvalModeTag) (m :: * -> *) r.
UnifiedBranching mode m =>
(If (IsConMode mode) (TryMerge m) (SymBranching m) => r) -> r
withBaseBranching @mode @m r
If (IsConMode mode) (TryMerge m) (SymBranching m) => r
If
  (IsConMode mode)
  (TryMerge (ExceptT e m))
  (SymBranching (ExceptT e m)) =>
r
r)
      (forall (mode :: EvalModeTag) (m :: * -> *) r.
UnifiedBranching mode m =>
(If (IsConMode mode) (TryMerge m) (SymBranching m) => r) -> r
withBaseBranching @mode @m r
If (IsConMode mode) (TryMerge m) (SymBranching m) => r
If
  (IsConMode mode)
  (TryMerge (ExceptT e m))
  (SymBranching (ExceptT e m)) =>
r
r)
  {-# INLINE withBaseBranching #-}

instance
  (UnifiedBranching mode m, Mergeable r, Mergeable a, Mergeable1 m) =>
  UnifiedSimpleMergeable mode (ContT r m a)
  where
  withBaseSimpleMergeable :: forall r.
(If
   (IsConMode mode)
   (() :: Constraint)
   (SimpleMergeable (ContT r m a)) =>
 r)
-> r
withBaseSimpleMergeable If
  (IsConMode mode)
  (() :: Constraint)
  (SimpleMergeable (ContT r m a)) =>
r
r =
    forall (mode :: EvalModeTag) r.
DecideEvalMode mode =>
((mode ~ 'C) => r) -> ((mode ~ 'S) => r) -> r
withMode @mode
      (forall (mode :: EvalModeTag) (m :: * -> *) r.
UnifiedBranching mode m =>
(If (IsConMode mode) (TryMerge m) (SymBranching m) => r) -> r
withBaseBranching @mode @m r
If
  (IsConMode mode)
  (() :: Constraint)
  (SimpleMergeable (ContT r m a)) =>
r
If (IsConMode mode) (TryMerge m) (SymBranching m) => r
r)
      (forall (mode :: EvalModeTag) (m :: * -> *) r.
UnifiedBranching mode m =>
(If (IsConMode mode) (TryMerge m) (SymBranching m) => r) -> r
withBaseBranching @mode @m r
If
  (IsConMode mode)
  (() :: Constraint)
  (SimpleMergeable (ContT r m a)) =>
r
If (IsConMode mode) (TryMerge m) (SymBranching m) => r
r)
  {-# INLINE withBaseSimpleMergeable #-}

instance
  (UnifiedBranching mode m, Mergeable r, Mergeable1 m) =>
  UnifiedSimpleMergeable1 mode (ContT r m)
  where
  withBaseSimpleMergeable1 :: forall r.
(If
   (IsConMode mode)
   (() :: Constraint)
   (SimpleMergeable1 (ContT r m)) =>
 r)
-> r
withBaseSimpleMergeable1 If
  (IsConMode mode)
  (() :: Constraint)
  (SimpleMergeable1 (ContT r m)) =>
r
r =
    forall (mode :: EvalModeTag) r.
DecideEvalMode mode =>
((mode ~ 'C) => r) -> ((mode ~ 'S) => r) -> r
withMode @mode
      (forall (mode :: EvalModeTag) (m :: * -> *) r.
UnifiedBranching mode m =>
(If (IsConMode mode) (TryMerge m) (SymBranching m) => r) -> r
withBaseBranching @mode @m r
If
  (IsConMode mode)
  (() :: Constraint)
  (SimpleMergeable1 (ContT r m)) =>
r
If (IsConMode mode) (TryMerge m) (SymBranching m) => r
r)
      (forall (mode :: EvalModeTag) (m :: * -> *) r.
UnifiedBranching mode m =>
(If (IsConMode mode) (TryMerge m) (SymBranching m) => r) -> r
withBaseBranching @mode @m r
If
  (IsConMode mode)
  (() :: Constraint)
  (SimpleMergeable1 (ContT r m)) =>
r
If (IsConMode mode) (TryMerge m) (SymBranching m) => r
r)
  {-# INLINE withBaseSimpleMergeable1 #-}

instance
  (UnifiedBranching mode m, Mergeable r, Mergeable1 m) =>
  UnifiedBranching mode (ContT r m)
  where
  withBaseBranching :: forall r.
(If
   (IsConMode mode)
   (TryMerge (ContT r m))
   (SymBranching (ContT r m)) =>
 r)
-> r
withBaseBranching If
  (IsConMode mode)
  (TryMerge (ContT r m))
  (SymBranching (ContT r m)) =>
r
r =
    forall (mode :: EvalModeTag) r.
DecideEvalMode mode =>
((mode ~ 'C) => r) -> ((mode ~ 'S) => r) -> r
withMode @mode
      (forall (mode :: EvalModeTag) (m :: * -> *) r.
UnifiedBranching mode m =>
(If (IsConMode mode) (TryMerge m) (SymBranching m) => r) -> r
withBaseBranching @mode @m r
If (IsConMode mode) (TryMerge m) (SymBranching m) => r
If
  (IsConMode mode)
  (TryMerge (ContT r m))
  (SymBranching (ContT r m)) =>
r
r)
      (forall (mode :: EvalModeTag) (m :: * -> *) r.
UnifiedBranching mode m =>
(If (IsConMode mode) (TryMerge m) (SymBranching m) => r) -> r
withBaseBranching @mode @m r
If (IsConMode mode) (TryMerge m) (SymBranching m) => r
If
  (IsConMode mode)
  (TryMerge (ContT r m))
  (SymBranching (ContT r m)) =>
r
r)
  {-# INLINE withBaseBranching #-}

instance
  (UnifiedBranching mode m, Mergeable w, Monoid w, Mergeable s, Mergeable a, Mergeable1 m) =>
  UnifiedSimpleMergeable mode (RWSLazy.RWST r w s m a)
  where
  withBaseSimpleMergeable :: forall r.
(If
   (IsConMode mode)
   (() :: Constraint)
   (SimpleMergeable (RWST r w s m a)) =>
 r)
-> r
withBaseSimpleMergeable If
  (IsConMode mode)
  (() :: Constraint)
  (SimpleMergeable (RWST r w s m a)) =>
r
r =
    forall (mode :: EvalModeTag) r.
DecideEvalMode mode =>
((mode ~ 'C) => r) -> ((mode ~ 'S) => r) -> r
withMode @mode
      (forall (mode :: EvalModeTag) (m :: * -> *) r.
UnifiedBranching mode m =>
(If (IsConMode mode) (TryMerge m) (SymBranching m) => r) -> r
withBaseBranching @mode @m r
If
  (IsConMode mode)
  (() :: Constraint)
  (SimpleMergeable (RWST r w s m a)) =>
r
If (IsConMode mode) (TryMerge m) (SymBranching m) => r
r)
      (forall (mode :: EvalModeTag) (m :: * -> *) r.
UnifiedBranching mode m =>
(If (IsConMode mode) (TryMerge m) (SymBranching m) => r) -> r
withBaseBranching @mode @m r
If
  (IsConMode mode)
  (() :: Constraint)
  (SimpleMergeable (RWST r w s m a)) =>
r
If (IsConMode mode) (TryMerge m) (SymBranching m) => r
r)
  {-# INLINE withBaseSimpleMergeable #-}

instance
  (UnifiedBranching mode m, Mergeable w, Monoid w, Mergeable s, Mergeable1 m) =>
  UnifiedSimpleMergeable1 mode (RWSLazy.RWST r w s m)
  where
  withBaseSimpleMergeable1 :: forall r.
(If
   (IsConMode mode)
   (() :: Constraint)
   (SimpleMergeable1 (RWST r w s m)) =>
 r)
-> r
withBaseSimpleMergeable1 If
  (IsConMode mode)
  (() :: Constraint)
  (SimpleMergeable1 (RWST r w s m)) =>
r
r =
    forall (mode :: EvalModeTag) r.
DecideEvalMode mode =>
((mode ~ 'C) => r) -> ((mode ~ 'S) => r) -> r
withMode @mode
      (forall (mode :: EvalModeTag) (m :: * -> *) r.
UnifiedBranching mode m =>
(If (IsConMode mode) (TryMerge m) (SymBranching m) => r) -> r
withBaseBranching @mode @m r
If
  (IsConMode mode)
  (() :: Constraint)
  (SimpleMergeable1 (RWST r w s m)) =>
r
If (IsConMode mode) (TryMerge m) (SymBranching m) => r
r)
      (forall (mode :: EvalModeTag) (m :: * -> *) r.
UnifiedBranching mode m =>
(If (IsConMode mode) (TryMerge m) (SymBranching m) => r) -> r
withBaseBranching @mode @m r
If
  (IsConMode mode)
  (() :: Constraint)
  (SimpleMergeable1 (RWST r w s m)) =>
r
If (IsConMode mode) (TryMerge m) (SymBranching m) => r
r)
  {-# INLINE withBaseSimpleMergeable1 #-}

instance
  (UnifiedBranching mode m, Mergeable s, Monoid w, Mergeable w) =>
  UnifiedBranching mode (RWSLazy.RWST r w s m)
  where
  withBaseBranching :: forall r.
(If
   (IsConMode mode)
   (TryMerge (RWST r w s m))
   (SymBranching (RWST r w s m)) =>
 r)
-> r
withBaseBranching If
  (IsConMode mode)
  (TryMerge (RWST r w s m))
  (SymBranching (RWST r w s m)) =>
r
r =
    forall (mode :: EvalModeTag) r.
DecideEvalMode mode =>
((mode ~ 'C) => r) -> ((mode ~ 'S) => r) -> r
withMode @mode
      (forall (mode :: EvalModeTag) (m :: * -> *) r.
UnifiedBranching mode m =>
(If (IsConMode mode) (TryMerge m) (SymBranching m) => r) -> r
withBaseBranching @mode @m r
If (IsConMode mode) (TryMerge m) (SymBranching m) => r
If
  (IsConMode mode)
  (TryMerge (RWST r w s m))
  (SymBranching (RWST r w s m)) =>
r
r)
      (forall (mode :: EvalModeTag) (m :: * -> *) r.
UnifiedBranching mode m =>
(If (IsConMode mode) (TryMerge m) (SymBranching m) => r) -> r
withBaseBranching @mode @m r
If (IsConMode mode) (TryMerge m) (SymBranching m) => r
If
  (IsConMode mode)
  (TryMerge (RWST r w s m))
  (SymBranching (RWST r w s m)) =>
r
r)
  {-# INLINE withBaseBranching #-}

instance
  (UnifiedBranching mode m, Mergeable w, Monoid w, Mergeable s, Mergeable a, Mergeable1 m) =>
  UnifiedSimpleMergeable mode (RWSStrict.RWST r w s m a)
  where
  withBaseSimpleMergeable :: forall r.
(If
   (IsConMode mode)
   (() :: Constraint)
   (SimpleMergeable (RWST r w s m a)) =>
 r)
-> r
withBaseSimpleMergeable If
  (IsConMode mode)
  (() :: Constraint)
  (SimpleMergeable (RWST r w s m a)) =>
r
r =
    forall (mode :: EvalModeTag) r.
DecideEvalMode mode =>
((mode ~ 'C) => r) -> ((mode ~ 'S) => r) -> r
withMode @mode
      (forall (mode :: EvalModeTag) (m :: * -> *) r.
UnifiedBranching mode m =>
(If (IsConMode mode) (TryMerge m) (SymBranching m) => r) -> r
withBaseBranching @mode @m r
If
  (IsConMode mode)
  (() :: Constraint)
  (SimpleMergeable (RWST r w s m a)) =>
r
If (IsConMode mode) (TryMerge m) (SymBranching m) => r
r)
      (forall (mode :: EvalModeTag) (m :: * -> *) r.
UnifiedBranching mode m =>
(If (IsConMode mode) (TryMerge m) (SymBranching m) => r) -> r
withBaseBranching @mode @m r
If
  (IsConMode mode)
  (() :: Constraint)
  (SimpleMergeable (RWST r w s m a)) =>
r
If (IsConMode mode) (TryMerge m) (SymBranching m) => r
r)
  {-# INLINE withBaseSimpleMergeable #-}

instance
  (UnifiedBranching mode m, Mergeable w, Monoid w, Mergeable s) =>
  UnifiedSimpleMergeable1 mode (RWSStrict.RWST r w s m)
  where
  withBaseSimpleMergeable1 :: forall r.
(If
   (IsConMode mode)
   (() :: Constraint)
   (SimpleMergeable1 (RWST r w s m)) =>
 r)
-> r
withBaseSimpleMergeable1 If
  (IsConMode mode)
  (() :: Constraint)
  (SimpleMergeable1 (RWST r w s m)) =>
r
r =
    forall (mode :: EvalModeTag) r.
DecideEvalMode mode =>
((mode ~ 'C) => r) -> ((mode ~ 'S) => r) -> r
withMode @mode
      (forall (mode :: EvalModeTag) (m :: * -> *) r.
UnifiedBranching mode m =>
(If (IsConMode mode) (TryMerge m) (SymBranching m) => r) -> r
withBaseBranching @mode @m r
If
  (IsConMode mode)
  (() :: Constraint)
  (SimpleMergeable1 (RWST r w s m)) =>
r
If (IsConMode mode) (TryMerge m) (SymBranching m) => r
r)
      (forall (mode :: EvalModeTag) (m :: * -> *) r.
UnifiedBranching mode m =>
(If (IsConMode mode) (TryMerge m) (SymBranching m) => r) -> r
withBaseBranching @mode @m r
If
  (IsConMode mode)
  (() :: Constraint)
  (SimpleMergeable1 (RWST r w s m)) =>
r
If (IsConMode mode) (TryMerge m) (SymBranching m) => r
r)
  {-# INLINE withBaseSimpleMergeable1 #-}

instance
  (UnifiedBranching mode m, Mergeable s, Monoid w, Mergeable w) =>
  UnifiedBranching mode (RWSStrict.RWST r w s m)
  where
  withBaseBranching :: forall r.
(If
   (IsConMode mode)
   (TryMerge (RWST r w s m))
   (SymBranching (RWST r w s m)) =>
 r)
-> r
withBaseBranching If
  (IsConMode mode)
  (TryMerge (RWST r w s m))
  (SymBranching (RWST r w s m)) =>
r
r =
    forall (mode :: EvalModeTag) r.
DecideEvalMode mode =>
((mode ~ 'C) => r) -> ((mode ~ 'S) => r) -> r
withMode @mode
      (forall (mode :: EvalModeTag) (m :: * -> *) r.
UnifiedBranching mode m =>
(If (IsConMode mode) (TryMerge m) (SymBranching m) => r) -> r
withBaseBranching @mode @m r
If (IsConMode mode) (TryMerge m) (SymBranching m) => r
If
  (IsConMode mode)
  (TryMerge (RWST r w s m))
  (SymBranching (RWST r w s m)) =>
r
r)
      (forall (mode :: EvalModeTag) (m :: * -> *) r.
UnifiedBranching mode m =>
(If (IsConMode mode) (TryMerge m) (SymBranching m) => r) -> r
withBaseBranching @mode @m r
If (IsConMode mode) (TryMerge m) (SymBranching m) => r
If
  (IsConMode mode)
  (TryMerge (RWST r w s m))
  (SymBranching (RWST r w s m)) =>
r
r)
  {-# INLINE withBaseBranching #-}