{-# LANGUAGE CPP #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DerivingVia #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE QuantifiedConstraints #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE Trustworthy #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}

-- |
-- Module      :   Grisette.Internal.Internal.Impl.Core.Data.Class.SimpleMergeable
-- Copyright   :   (c) Sirui Lu 2021-2024
-- License     :   BSD-3-Clause (see the LICENSE file)
--
-- Maintainer  :   siruilu@cs.washington.edu
-- Stability   :   Experimental
-- Portability :   GHC only
module Grisette.Internal.Internal.Impl.Core.Data.Class.SimpleMergeable () where

import Control.Monad.Except (ExceptT (ExceptT))
import Control.Monad.Identity
  ( Identity,
    IdentityT (IdentityT),
  )
import qualified Control.Monad.RWS.Lazy as RWSLazy
import qualified Control.Monad.RWS.Strict as RWSStrict
import Control.Monad.Reader (ReaderT (ReaderT))
import qualified Control.Monad.State.Lazy as StateLazy
import qualified Control.Monad.State.Strict as StateStrict
import Control.Monad.Trans.Cont (ContT (ContT))
import Control.Monad.Trans.Maybe (MaybeT (MaybeT))
import qualified Control.Monad.Writer.Lazy as WriterLazy
import qualified Control.Monad.Writer.Strict as WriterStrict
import Data.Functor.Compose (Compose (Compose))
import Data.Functor.Const (Const)
import Data.Functor.Product (Product)
import Data.Monoid (Alt, Ap, Endo (Endo))
import qualified Data.Monoid as Monoid
import Data.Ord (Down)
import Data.Proxy (Proxy)
import GHC.Generics
  ( K1 (K1),
    M1 (M1),
    Par1 (Par1),
    Rec1 (Rec1),
    U1,
    V1,
    (:.:) (Comp1),
    type (:*:),
  )
import GHC.TypeNats (KnownNat, type (<=))
import Generics.Deriving (Default (Default), Default1 (Default1))
import Grisette.Internal.Core.Control.Exception (AssertionError)
import Grisette.Internal.Core.Data.Class.ITEOp (ITEOp (symIte))
import Grisette.Internal.Core.Data.Class.Mergeable
  ( Mergeable (rootStrategy),
    Mergeable1 (liftRootStrategy),
    Mergeable2 (liftRootStrategy2),
    Mergeable3 (liftRootStrategy3),
    MergingStrategy (SimpleStrategy),
  )
import Grisette.Internal.Internal.Decl.Core.Data.Class.SimpleMergeable
  ( SimpleMergeable (mrgIte),
    SimpleMergeable1 (liftMrgIte),
    SimpleMergeable2 (liftMrgIte2),
    SymBranching (mrgIfPropagatedStrategy, mrgIfWithStrategy),
    mrgIf,
    mrgIte1,
  )
import Grisette.Internal.Internal.Impl.Core.Data.Class.TryMerge ()
import Grisette.Internal.SymPrim.FP (ValidFP)
import Grisette.Internal.SymPrim.GeneralFun (type (-->))
import Grisette.Internal.SymPrim.SymAlgReal (SymAlgReal)
import Grisette.Internal.SymPrim.SymBV
  ( SymIntN,
    SymWordN,
  )
import Grisette.Internal.SymPrim.SymFP (SymFP, SymFPRoundingMode)
import Grisette.Internal.SymPrim.SymGeneralFun (type (-~>))
import Grisette.Internal.SymPrim.SymInteger (SymInteger)
import Grisette.Internal.SymPrim.SymTabularFun (type (=~>))
import Grisette.Internal.TH.Derivation.Derive (derive)

-- $setup
-- >>> import Grisette.Core
-- >>> import Grisette.SymPrim
-- >>> import Control.Monad.Identity

derive
  [ ''(,),
    ''(,,),
    ''(,,,),
    ''(,,,,),
    ''(,,,,,),
    ''(,,,,,,),
    ''(,,,,,,,),
    ''(,,,,,,,,),
    ''(,,,,,,,,,),
    ''(,,,,,,,,,,),
    ''(,,,,,,,,,,,),
    ''(,,,,,,,,,,,,),
    ''(,,,,,,,,,,,,,),
    ''(,,,,,,,,,,,,,,)
  ]
  [''SimpleMergeable, ''SimpleMergeable1, ''SimpleMergeable2]

derive
  [ ''Identity,
    ''Monoid.Dual,
    ''Monoid.Sum,
    ''Monoid.Product,
    ''Down
  ]
  [''SimpleMergeable, ''SimpleMergeable1]

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

instance SimpleMergeable (Proxy a) where
  mrgIte :: SymBool -> Proxy a -> Proxy a -> Proxy a
mrgIte SymBool
_ Proxy a
l Proxy a
_ = Proxy a
l
  {-# INLINE mrgIte #-}

instance SimpleMergeable1 Proxy where
  liftMrgIte :: forall a.
(SymBool -> a -> a -> a)
-> SymBool -> Proxy a -> Proxy a -> Proxy a
liftMrgIte SymBool -> a -> a -> a
_ SymBool
_ Proxy a
l Proxy a
_ = Proxy a
l
  {-# INLINE liftMrgIte #-}

instance (SimpleMergeable b) => SimpleMergeable (a -> b) where
  mrgIte :: SymBool -> (a -> b) -> (a -> b) -> a -> b
mrgIte = SymBool -> (a -> b) -> (a -> b) -> a -> b
forall (u :: * -> *) a.
(SimpleMergeable1 u, SimpleMergeable a) =>
SymBool -> u a -> u a -> u a
mrgIte1
  {-# INLINE mrgIte #-}

instance SimpleMergeable1 ((->) a) where
  liftMrgIte :: forall a.
(SymBool -> a -> a -> a)
-> SymBool -> (a -> a) -> (a -> a) -> a -> a
liftMrgIte SymBool -> a -> a -> a
ms SymBool
cond a -> a
t a -> a
f a
v = SymBool -> a -> a -> a
ms SymBool
cond (a -> a
t a
v) (a -> a
f a
v)
  {-# INLINE liftMrgIte #-}

instance SimpleMergeable2 (->) where
  liftMrgIte2 :: forall a b.
(SymBool -> a -> a -> a)
-> (SymBool -> b -> b -> b)
-> SymBool
-> (a -> b)
-> (a -> b)
-> a -> b
liftMrgIte2 SymBool -> a -> a -> a
_ SymBool -> b -> b -> b
ms SymBool
cond a -> b
t a -> b
f a
v = SymBool -> b -> b -> b
ms SymBool
cond (a -> b
t a
v) (a -> b
f a
v)
  {-# INLINE liftMrgIte2 #-}

-- MaybeT
instance (SymBranching m, Mergeable a) => SimpleMergeable (MaybeT m a) where
  mrgIte :: SymBool -> MaybeT m a -> MaybeT m a -> MaybeT m a
mrgIte = SymBool -> MaybeT m a -> MaybeT m a -> MaybeT m a
forall (u :: * -> *) a.
(SymBranching u, Mergeable a) =>
SymBool -> u a -> u a -> u a
mrgIf
  {-# INLINE mrgIte #-}

instance (SymBranching m) => SimpleMergeable1 (MaybeT m) where
  liftMrgIte :: forall a.
(SymBool -> a -> a -> a)
-> SymBool -> MaybeT m a -> MaybeT m a -> MaybeT m a
liftMrgIte SymBool -> a -> a -> a
m = MergingStrategy a
-> SymBool -> MaybeT m a -> MaybeT m a -> MaybeT m a
forall a.
MergingStrategy a
-> SymBool -> MaybeT m a -> MaybeT m a -> MaybeT m a
forall (u :: * -> *) a.
SymBranching u =>
MergingStrategy a -> SymBool -> u a -> u a -> u a
mrgIfWithStrategy ((SymBool -> a -> a -> a) -> MergingStrategy a
forall a. (SymBool -> a -> a -> a) -> MergingStrategy a
SimpleStrategy SymBool -> a -> a -> a
m)
  {-# INLINE liftMrgIte #-}

instance (SymBranching m) => SymBranching (MaybeT m) where
  mrgIfWithStrategy :: forall a.
MergingStrategy a
-> SymBool -> MaybeT m a -> MaybeT m a -> MaybeT m a
mrgIfWithStrategy MergingStrategy a
strategy SymBool
cond (MaybeT m (Maybe a)
l) (MaybeT m (Maybe a)
r) =
    m (Maybe a) -> MaybeT m a
forall (m :: * -> *) a. m (Maybe a) -> MaybeT m a
MaybeT (m (Maybe a) -> MaybeT m a) -> m (Maybe a) -> MaybeT m a
forall a b. (a -> b) -> a -> b
$ MergingStrategy (Maybe a)
-> SymBool -> m (Maybe a) -> m (Maybe a) -> m (Maybe a)
forall a. MergingStrategy a -> SymBool -> m a -> m a -> m a
forall (u :: * -> *) a.
SymBranching u =>
MergingStrategy a -> SymBool -> u a -> u a -> u a
mrgIfWithStrategy (MergingStrategy a -> MergingStrategy (Maybe a)
forall a. MergingStrategy a -> MergingStrategy (Maybe a)
forall (u :: * -> *) a.
Mergeable1 u =>
MergingStrategy a -> MergingStrategy (u a)
liftRootStrategy MergingStrategy a
strategy) SymBool
cond m (Maybe a)
l m (Maybe a)
r
  {-# INLINE mrgIfWithStrategy #-}
  mrgIfPropagatedStrategy :: forall a. SymBool -> MaybeT m a -> MaybeT m a -> MaybeT m a
mrgIfPropagatedStrategy SymBool
cond (MaybeT m (Maybe a)
l) (MaybeT m (Maybe a)
r) =
    m (Maybe a) -> MaybeT m a
forall (m :: * -> *) a. m (Maybe a) -> MaybeT m a
MaybeT (m (Maybe a) -> MaybeT m a) -> m (Maybe a) -> MaybeT m a
forall a b. (a -> b) -> a -> b
$ SymBool -> m (Maybe a) -> m (Maybe a) -> m (Maybe a)
forall a. SymBool -> m a -> m a -> m a
forall (u :: * -> *) a.
SymBranching u =>
SymBool -> u a -> u a -> u a
mrgIfPropagatedStrategy SymBool
cond m (Maybe a)
l m (Maybe a)
r
  {-# INLINE mrgIfPropagatedStrategy #-}

-- ExceptT
instance
  (SymBranching m, Mergeable e, Mergeable a) =>
  SimpleMergeable (ExceptT e m a)
  where
  mrgIte :: SymBool -> ExceptT e m a -> ExceptT e m a -> ExceptT e m a
mrgIte = SymBool -> ExceptT e m a -> ExceptT e m a -> ExceptT e m a
forall (u :: * -> *) a.
(SymBranching u, Mergeable a) =>
SymBool -> u a -> u a -> u a
mrgIf
  {-# INLINE mrgIte #-}

instance
  (SymBranching m, Mergeable e) =>
  SimpleMergeable1 (ExceptT e m)
  where
  liftMrgIte :: forall a.
(SymBool -> a -> a -> a)
-> SymBool -> ExceptT e m a -> ExceptT e m a -> ExceptT e m a
liftMrgIte SymBool -> a -> a -> a
m = MergingStrategy a
-> SymBool -> ExceptT e m a -> ExceptT e m a -> ExceptT e m a
forall a.
MergingStrategy a
-> SymBool -> ExceptT e m a -> ExceptT e m a -> ExceptT e m a
forall (u :: * -> *) a.
SymBranching u =>
MergingStrategy a -> SymBool -> u a -> u a -> u a
mrgIfWithStrategy ((SymBool -> a -> a -> a) -> MergingStrategy a
forall a. (SymBool -> a -> a -> a) -> MergingStrategy a
SimpleStrategy SymBool -> a -> a -> a
m)
  {-# INLINE liftMrgIte #-}

instance
  (SymBranching m, Mergeable e) =>
  SymBranching (ExceptT e m)
  where
  mrgIfWithStrategy :: forall a.
MergingStrategy a
-> SymBool -> ExceptT e m a -> ExceptT e m a -> ExceptT e m a
mrgIfWithStrategy MergingStrategy a
s SymBool
cond (ExceptT m (Either e a)
t) (ExceptT m (Either e a)
f) =
    m (Either e a) -> ExceptT e m a
forall e (m :: * -> *) a. m (Either e a) -> ExceptT e m a
ExceptT (m (Either e a) -> ExceptT e m a)
-> m (Either e a) -> ExceptT e m a
forall a b. (a -> b) -> a -> b
$ MergingStrategy (Either e a)
-> SymBool -> m (Either e a) -> m (Either e a) -> m (Either e a)
forall a. MergingStrategy a -> SymBool -> m a -> m a -> m a
forall (u :: * -> *) a.
SymBranching u =>
MergingStrategy a -> SymBool -> u a -> u a -> u a
mrgIfWithStrategy (MergingStrategy a -> MergingStrategy (Either e a)
forall a. MergingStrategy a -> MergingStrategy (Either e a)
forall (u :: * -> *) a.
Mergeable1 u =>
MergingStrategy a -> MergingStrategy (u a)
liftRootStrategy MergingStrategy a
s) SymBool
cond m (Either e a)
t m (Either e a)
f
  {-# INLINE mrgIfWithStrategy #-}
  mrgIfPropagatedStrategy :: forall a.
SymBool -> ExceptT e m a -> ExceptT e m a -> ExceptT e m a
mrgIfPropagatedStrategy SymBool
cond (ExceptT m (Either e a)
t) (ExceptT m (Either e a)
f) =
    m (Either e a) -> ExceptT e m a
forall e (m :: * -> *) a. m (Either e a) -> ExceptT e m a
ExceptT (m (Either e a) -> ExceptT e m a)
-> m (Either e a) -> ExceptT e m a
forall a b. (a -> b) -> a -> b
$ SymBool -> m (Either e a) -> m (Either e a) -> m (Either e a)
forall a. SymBool -> m a -> m a -> m a
forall (u :: * -> *) a.
SymBranching u =>
SymBool -> u a -> u a -> u a
mrgIfPropagatedStrategy SymBool
cond m (Either e a)
t m (Either e a)
f
  {-# INLINE mrgIfPropagatedStrategy #-}

-- StateT
instance
  (Mergeable s, Mergeable a, SymBranching m) =>
  SimpleMergeable (StateLazy.StateT s m a)
  where
  mrgIte :: SymBool -> StateT s m a -> StateT s m a -> StateT s m a
mrgIte = SymBool -> StateT s m a -> StateT s m a -> StateT s m a
forall (u :: * -> *) a.
(SymBranching u, Mergeable a) =>
SymBool -> u a -> u a -> u a
mrgIf
  {-# INLINE mrgIte #-}

instance
  (Mergeable s, SymBranching m) =>
  SimpleMergeable1 (StateLazy.StateT s m)
  where
  liftMrgIte :: forall a.
(SymBool -> a -> a -> a)
-> SymBool -> StateT s m a -> StateT s m a -> StateT s m a
liftMrgIte SymBool -> a -> a -> a
m = MergingStrategy a
-> SymBool -> StateT s m a -> StateT s m a -> StateT s m a
forall a.
MergingStrategy a
-> SymBool -> StateT s m a -> StateT s m a -> StateT s m a
forall (u :: * -> *) a.
SymBranching u =>
MergingStrategy a -> SymBool -> u a -> u a -> u a
mrgIfWithStrategy ((SymBool -> a -> a -> a) -> MergingStrategy a
forall a. (SymBool -> a -> a -> a) -> MergingStrategy a
SimpleStrategy SymBool -> a -> a -> a
m)
  {-# INLINE liftMrgIte #-}

instance
  (Mergeable s, SymBranching m) =>
  SymBranching (StateLazy.StateT s m)
  where
  mrgIfWithStrategy :: forall a.
MergingStrategy a
-> SymBool -> StateT s m a -> StateT s m a -> StateT s m a
mrgIfWithStrategy MergingStrategy a
s SymBool
cond (StateLazy.StateT s -> m (a, s)
t) (StateLazy.StateT s -> m (a, s)
f) =
    (s -> m (a, s)) -> StateT s m a
forall s (m :: * -> *) a. (s -> m (a, s)) -> StateT s m a
StateLazy.StateT ((s -> m (a, s)) -> StateT s m a)
-> (s -> m (a, s)) -> StateT s m a
forall a b. (a -> b) -> a -> b
$ \s
v ->
      MergingStrategy (a, s)
-> SymBool -> m (a, s) -> m (a, s) -> m (a, s)
forall a. MergingStrategy a -> SymBool -> m a -> m a -> m a
forall (u :: * -> *) a.
SymBranching u =>
MergingStrategy a -> SymBool -> u a -> u a -> u a
mrgIfWithStrategy
        (MergingStrategy a -> MergingStrategy s -> MergingStrategy (a, s)
forall a b.
MergingStrategy a -> MergingStrategy b -> MergingStrategy (a, b)
forall (u :: * -> * -> *) a b.
Mergeable2 u =>
MergingStrategy a -> MergingStrategy b -> MergingStrategy (u a b)
liftRootStrategy2 MergingStrategy a
s MergingStrategy s
forall a. Mergeable a => MergingStrategy a
rootStrategy)
        SymBool
cond
        (s -> m (a, s)
t s
v)
        (s -> m (a, s)
f s
v)
  {-# INLINE mrgIfWithStrategy #-}
  mrgIfPropagatedStrategy :: forall a. SymBool -> StateT s m a -> StateT s m a -> StateT s m a
mrgIfPropagatedStrategy SymBool
cond (StateLazy.StateT s -> m (a, s)
t) (StateLazy.StateT s -> m (a, s)
f) =
    (s -> m (a, s)) -> StateT s m a
forall s (m :: * -> *) a. (s -> m (a, s)) -> StateT s m a
StateLazy.StateT ((s -> m (a, s)) -> StateT s m a)
-> (s -> m (a, s)) -> StateT s m a
forall a b. (a -> b) -> a -> b
$ \s
v -> SymBool -> m (a, s) -> m (a, s) -> m (a, s)
forall a. SymBool -> m a -> m a -> m a
forall (u :: * -> *) a.
SymBranching u =>
SymBool -> u a -> u a -> u a
mrgIfPropagatedStrategy SymBool
cond (s -> m (a, s)
t s
v) (s -> m (a, s)
f s
v)
  {-# INLINE mrgIfPropagatedStrategy #-}

instance
  (Mergeable s, Mergeable a, SymBranching m) =>
  SimpleMergeable (StateStrict.StateT s m a)
  where
  mrgIte :: SymBool -> StateT s m a -> StateT s m a -> StateT s m a
mrgIte = SymBool -> StateT s m a -> StateT s m a -> StateT s m a
forall (u :: * -> *) a.
(SymBranching u, Mergeable a) =>
SymBool -> u a -> u a -> u a
mrgIf
  {-# INLINE mrgIte #-}

instance
  (Mergeable s, SymBranching m) =>
  SimpleMergeable1 (StateStrict.StateT s m)
  where
  liftMrgIte :: forall a.
(SymBool -> a -> a -> a)
-> SymBool -> StateT s m a -> StateT s m a -> StateT s m a
liftMrgIte SymBool -> a -> a -> a
m = MergingStrategy a
-> SymBool -> StateT s m a -> StateT s m a -> StateT s m a
forall a.
MergingStrategy a
-> SymBool -> StateT s m a -> StateT s m a -> StateT s m a
forall (u :: * -> *) a.
SymBranching u =>
MergingStrategy a -> SymBool -> u a -> u a -> u a
mrgIfWithStrategy ((SymBool -> a -> a -> a) -> MergingStrategy a
forall a. (SymBool -> a -> a -> a) -> MergingStrategy a
SimpleStrategy SymBool -> a -> a -> a
m)
  {-# INLINE liftMrgIte #-}

instance
  (Mergeable s, SymBranching m) =>
  SymBranching (StateStrict.StateT s m)
  where
  mrgIfWithStrategy :: forall a.
MergingStrategy a
-> SymBool -> StateT s m a -> StateT s m a -> StateT s m a
mrgIfWithStrategy MergingStrategy a
s SymBool
cond (StateStrict.StateT s -> m (a, s)
t) (StateStrict.StateT s -> m (a, s)
f) =
    (s -> m (a, s)) -> StateT s m a
forall s (m :: * -> *) a. (s -> m (a, s)) -> StateT s m a
StateStrict.StateT ((s -> m (a, s)) -> StateT s m a)
-> (s -> m (a, s)) -> StateT s m a
forall a b. (a -> b) -> a -> b
$
      \s
v ->
        MergingStrategy (a, s)
-> SymBool -> m (a, s) -> m (a, s) -> m (a, s)
forall a. MergingStrategy a -> SymBool -> m a -> m a -> m a
forall (u :: * -> *) a.
SymBranching u =>
MergingStrategy a -> SymBool -> u a -> u a -> u a
mrgIfWithStrategy (MergingStrategy a -> MergingStrategy s -> MergingStrategy (a, s)
forall a b.
MergingStrategy a -> MergingStrategy b -> MergingStrategy (a, b)
forall (u :: * -> * -> *) a b.
Mergeable2 u =>
MergingStrategy a -> MergingStrategy b -> MergingStrategy (u a b)
liftRootStrategy2 MergingStrategy a
s MergingStrategy s
forall a. Mergeable a => MergingStrategy a
rootStrategy) SymBool
cond (s -> m (a, s)
t s
v) (s -> m (a, s)
f s
v)
  {-# INLINE mrgIfWithStrategy #-}
  mrgIfPropagatedStrategy :: forall a. SymBool -> StateT s m a -> StateT s m a -> StateT s m a
mrgIfPropagatedStrategy SymBool
cond (StateStrict.StateT s -> m (a, s)
t) (StateStrict.StateT s -> m (a, s)
f) =
    (s -> m (a, s)) -> StateT s m a
forall s (m :: * -> *) a. (s -> m (a, s)) -> StateT s m a
StateStrict.StateT ((s -> m (a, s)) -> StateT s m a)
-> (s -> m (a, s)) -> StateT s m a
forall a b. (a -> b) -> a -> b
$ \s
v -> SymBool -> m (a, s) -> m (a, s) -> m (a, s)
forall a. SymBool -> m a -> m a -> m a
forall (u :: * -> *) a.
SymBranching u =>
SymBool -> u a -> u a -> u a
mrgIfPropagatedStrategy SymBool
cond (s -> m (a, s)
t s
v) (s -> m (a, s)
f s
v)
  {-# INLINE mrgIfPropagatedStrategy #-}

-- WriterT
instance
  (Mergeable s, Mergeable a, SymBranching m, Monoid s) =>
  SimpleMergeable (WriterLazy.WriterT s m a)
  where
  mrgIte :: SymBool -> WriterT s m a -> WriterT s m a -> WriterT s m a
mrgIte = SymBool -> WriterT s m a -> WriterT s m a -> WriterT s m a
forall (u :: * -> *) a.
(SymBranching u, Mergeable a) =>
SymBool -> u a -> u a -> u a
mrgIf
  {-# INLINE mrgIte #-}

instance
  (Mergeable s, SymBranching m, Monoid s) =>
  SimpleMergeable1 (WriterLazy.WriterT s m)
  where
  liftMrgIte :: forall a.
(SymBool -> a -> a -> a)
-> SymBool -> WriterT s m a -> WriterT s m a -> WriterT s m a
liftMrgIte SymBool -> a -> a -> a
m = MergingStrategy a
-> SymBool -> WriterT s m a -> WriterT s m a -> WriterT s m a
forall a.
MergingStrategy a
-> SymBool -> WriterT s m a -> WriterT s m a -> WriterT s m a
forall (u :: * -> *) a.
SymBranching u =>
MergingStrategy a -> SymBool -> u a -> u a -> u a
mrgIfWithStrategy ((SymBool -> a -> a -> a) -> MergingStrategy a
forall a. (SymBool -> a -> a -> a) -> MergingStrategy a
SimpleStrategy SymBool -> a -> a -> a
m)
  {-# INLINE liftMrgIte #-}

instance
  (Mergeable s, SymBranching m, Monoid s) =>
  SymBranching (WriterLazy.WriterT s m)
  where
  mrgIfWithStrategy :: forall a.
MergingStrategy a
-> SymBool -> WriterT s m a -> WriterT s m a -> WriterT s m a
mrgIfWithStrategy MergingStrategy a
s SymBool
cond (WriterLazy.WriterT m (a, s)
t) (WriterLazy.WriterT m (a, s)
f) =
    m (a, s) -> WriterT s m a
forall w (m :: * -> *) a. m (a, w) -> WriterT w m a
WriterLazy.WriterT (m (a, s) -> WriterT s m a) -> m (a, s) -> WriterT s m a
forall a b. (a -> b) -> a -> b
$
      MergingStrategy (a, s)
-> SymBool -> m (a, s) -> m (a, s) -> m (a, s)
forall a. MergingStrategy a -> SymBool -> m a -> m a -> m a
forall (u :: * -> *) a.
SymBranching u =>
MergingStrategy a -> SymBool -> u a -> u a -> u a
mrgIfWithStrategy (MergingStrategy a -> MergingStrategy s -> MergingStrategy (a, s)
forall a b.
MergingStrategy a -> MergingStrategy b -> MergingStrategy (a, b)
forall (u :: * -> * -> *) a b.
Mergeable2 u =>
MergingStrategy a -> MergingStrategy b -> MergingStrategy (u a b)
liftRootStrategy2 MergingStrategy a
s MergingStrategy s
forall a. Mergeable a => MergingStrategy a
rootStrategy) SymBool
cond m (a, s)
t m (a, s)
f
  {-# INLINE mrgIfWithStrategy #-}
  mrgIfPropagatedStrategy :: forall a.
SymBool -> WriterT s m a -> WriterT s m a -> WriterT s m a
mrgIfPropagatedStrategy SymBool
cond (WriterLazy.WriterT m (a, s)
t) (WriterLazy.WriterT m (a, s)
f) =
    m (a, s) -> WriterT s m a
forall w (m :: * -> *) a. m (a, w) -> WriterT w m a
WriterLazy.WriterT (m (a, s) -> WriterT s m a) -> m (a, s) -> WriterT s m a
forall a b. (a -> b) -> a -> b
$ SymBool -> m (a, s) -> m (a, s) -> m (a, s)
forall a. SymBool -> m a -> m a -> m a
forall (u :: * -> *) a.
SymBranching u =>
SymBool -> u a -> u a -> u a
mrgIfPropagatedStrategy SymBool
cond m (a, s)
t m (a, s)
f
  {-# INLINE mrgIfPropagatedStrategy #-}

instance
  (Mergeable s, Mergeable a, SymBranching m, Monoid s) =>
  SimpleMergeable (WriterStrict.WriterT s m a)
  where
  mrgIte :: SymBool -> WriterT s m a -> WriterT s m a -> WriterT s m a
mrgIte = SymBool -> WriterT s m a -> WriterT s m a -> WriterT s m a
forall (u :: * -> *) a.
(SymBranching u, Mergeable a) =>
SymBool -> u a -> u a -> u a
mrgIf
  {-# INLINE mrgIte #-}

instance
  (Mergeable s, SymBranching m, Monoid s) =>
  SimpleMergeable1 (WriterStrict.WriterT s m)
  where
  liftMrgIte :: forall a.
(SymBool -> a -> a -> a)
-> SymBool -> WriterT s m a -> WriterT s m a -> WriterT s m a
liftMrgIte SymBool -> a -> a -> a
m = MergingStrategy a
-> SymBool -> WriterT s m a -> WriterT s m a -> WriterT s m a
forall a.
MergingStrategy a
-> SymBool -> WriterT s m a -> WriterT s m a -> WriterT s m a
forall (u :: * -> *) a.
SymBranching u =>
MergingStrategy a -> SymBool -> u a -> u a -> u a
mrgIfWithStrategy ((SymBool -> a -> a -> a) -> MergingStrategy a
forall a. (SymBool -> a -> a -> a) -> MergingStrategy a
SimpleStrategy SymBool -> a -> a -> a
m)
  {-# INLINE liftMrgIte #-}

instance
  (Mergeable s, SymBranching m, Monoid s) =>
  SymBranching (WriterStrict.WriterT s m)
  where
  mrgIfWithStrategy :: forall a.
MergingStrategy a
-> SymBool -> WriterT s m a -> WriterT s m a -> WriterT s m a
mrgIfWithStrategy MergingStrategy a
s SymBool
cond (WriterStrict.WriterT m (a, s)
t) (WriterStrict.WriterT m (a, s)
f) =
    m (a, s) -> WriterT s m a
forall w (m :: * -> *) a. m (a, w) -> WriterT w m a
WriterStrict.WriterT (m (a, s) -> WriterT s m a) -> m (a, s) -> WriterT s m a
forall a b. (a -> b) -> a -> b
$
      MergingStrategy (a, s)
-> SymBool -> m (a, s) -> m (a, s) -> m (a, s)
forall a. MergingStrategy a -> SymBool -> m a -> m a -> m a
forall (u :: * -> *) a.
SymBranching u =>
MergingStrategy a -> SymBool -> u a -> u a -> u a
mrgIfWithStrategy (MergingStrategy a -> MergingStrategy s -> MergingStrategy (a, s)
forall a b.
MergingStrategy a -> MergingStrategy b -> MergingStrategy (a, b)
forall (u :: * -> * -> *) a b.
Mergeable2 u =>
MergingStrategy a -> MergingStrategy b -> MergingStrategy (u a b)
liftRootStrategy2 MergingStrategy a
s MergingStrategy s
forall a. Mergeable a => MergingStrategy a
rootStrategy) SymBool
cond m (a, s)
t m (a, s)
f
  {-# INLINE mrgIfWithStrategy #-}
  mrgIfPropagatedStrategy :: forall a.
SymBool -> WriterT s m a -> WriterT s m a -> WriterT s m a
mrgIfPropagatedStrategy
    SymBool
cond
    (WriterStrict.WriterT m (a, s)
t)
    (WriterStrict.WriterT m (a, s)
f) =
      m (a, s) -> WriterT s m a
forall w (m :: * -> *) a. m (a, w) -> WriterT w m a
WriterStrict.WriterT (m (a, s) -> WriterT s m a) -> m (a, s) -> WriterT s m a
forall a b. (a -> b) -> a -> b
$ SymBool -> m (a, s) -> m (a, s) -> m (a, s)
forall a. SymBool -> m a -> m a -> m a
forall (u :: * -> *) a.
SymBranching u =>
SymBool -> u a -> u a -> u a
mrgIfPropagatedStrategy SymBool
cond m (a, s)
t m (a, s)
f
  {-# INLINE mrgIfPropagatedStrategy #-}

-- ReaderT
instance
  (Mergeable a, SymBranching m) =>
  SimpleMergeable (ReaderT s m a)
  where
  mrgIte :: SymBool -> ReaderT s m a -> ReaderT s m a -> ReaderT s m a
mrgIte = SymBool -> ReaderT s m a -> ReaderT s m a -> ReaderT s m a
forall (u :: * -> *) a.
(SymBranching u, Mergeable a) =>
SymBool -> u a -> u a -> u a
mrgIf
  {-# INLINE mrgIte #-}

instance
  (SymBranching m) =>
  SimpleMergeable1 (ReaderT s m)
  where
  liftMrgIte :: forall a.
(SymBool -> a -> a -> a)
-> SymBool -> ReaderT s m a -> ReaderT s m a -> ReaderT s m a
liftMrgIte SymBool -> a -> a -> a
m = MergingStrategy a
-> SymBool -> ReaderT s m a -> ReaderT s m a -> ReaderT s m a
forall a.
MergingStrategy a
-> SymBool -> ReaderT s m a -> ReaderT s m a -> ReaderT s m a
forall (u :: * -> *) a.
SymBranching u =>
MergingStrategy a -> SymBool -> u a -> u a -> u a
mrgIfWithStrategy ((SymBool -> a -> a -> a) -> MergingStrategy a
forall a. (SymBool -> a -> a -> a) -> MergingStrategy a
SimpleStrategy SymBool -> a -> a -> a
m)
  {-# INLINE liftMrgIte #-}

instance
  (SymBranching m) =>
  SymBranching (ReaderT s m)
  where
  mrgIfWithStrategy :: forall a.
MergingStrategy a
-> SymBool -> ReaderT s m a -> ReaderT s m a -> ReaderT s m a
mrgIfWithStrategy MergingStrategy a
s SymBool
cond (ReaderT s -> m a
t) (ReaderT s -> m a
f) =
    (s -> m a) -> ReaderT s m a
forall r (m :: * -> *) a. (r -> m a) -> ReaderT r m a
ReaderT ((s -> m a) -> ReaderT s m a) -> (s -> m a) -> ReaderT s m a
forall a b. (a -> b) -> a -> b
$ \s
v -> MergingStrategy a -> SymBool -> m a -> m a -> m a
forall a. MergingStrategy a -> SymBool -> m a -> m a -> m a
forall (u :: * -> *) a.
SymBranching u =>
MergingStrategy a -> SymBool -> u a -> u a -> u a
mrgIfWithStrategy MergingStrategy a
s SymBool
cond (s -> m a
t s
v) (s -> m a
f s
v)
  {-# INLINE mrgIfWithStrategy #-}
  mrgIfPropagatedStrategy :: forall a.
SymBool -> ReaderT s m a -> ReaderT s m a -> ReaderT s m a
mrgIfPropagatedStrategy SymBool
cond (ReaderT s -> m a
t) (ReaderT s -> m a
f) =
    (s -> m a) -> ReaderT s m a
forall r (m :: * -> *) a. (r -> m a) -> ReaderT r m a
ReaderT ((s -> m a) -> ReaderT s m a) -> (s -> m a) -> ReaderT s m a
forall a b. (a -> b) -> a -> b
$ \s
v -> SymBool -> m a -> m a -> m a
forall a. SymBool -> m a -> m a -> m a
forall (u :: * -> *) a.
SymBranching u =>
SymBool -> u a -> u a -> u a
mrgIfPropagatedStrategy SymBool
cond (s -> m a
t s
v) (s -> m a
f s
v)
  {-# INLINE mrgIfPropagatedStrategy #-}

-- IdentityT
instance
  (SymBranching m, Mergeable a) =>
  SimpleMergeable (IdentityT m a)
  where
  mrgIte :: SymBool -> IdentityT m a -> IdentityT m a -> IdentityT m a
mrgIte = SymBool -> IdentityT m a -> IdentityT m a -> IdentityT m a
forall (u :: * -> *) a.
(SymBranching u, Mergeable a) =>
SymBool -> u a -> u a -> u a
mrgIf
  {-# INLINE mrgIte #-}

instance (SymBranching m) => SimpleMergeable1 (IdentityT m) where
  liftMrgIte :: forall a.
(SymBool -> a -> a -> a)
-> SymBool -> IdentityT m a -> IdentityT m a -> IdentityT m a
liftMrgIte SymBool -> a -> a -> a
m = MergingStrategy a
-> SymBool -> IdentityT m a -> IdentityT m a -> IdentityT m a
forall a.
MergingStrategy a
-> SymBool -> IdentityT m a -> IdentityT m a -> IdentityT m a
forall (u :: * -> *) a.
SymBranching u =>
MergingStrategy a -> SymBool -> u a -> u a -> u a
mrgIfWithStrategy ((SymBool -> a -> a -> a) -> MergingStrategy a
forall a. (SymBool -> a -> a -> a) -> MergingStrategy a
SimpleStrategy SymBool -> a -> a -> a
m)
  {-# INLINE liftMrgIte #-}

instance (SymBranching m) => SymBranching (IdentityT m) where
  mrgIfWithStrategy :: forall a.
MergingStrategy a
-> SymBool -> IdentityT m a -> IdentityT m a -> IdentityT m a
mrgIfWithStrategy MergingStrategy a
s SymBool
cond (IdentityT m a
l) (IdentityT m a
r) =
    m a -> IdentityT m a
forall {k} (f :: k -> *) (a :: k). f a -> IdentityT f a
IdentityT (m a -> IdentityT m a) -> m a -> IdentityT m a
forall a b. (a -> b) -> a -> b
$ MergingStrategy a -> SymBool -> m a -> m a -> m a
forall a. MergingStrategy a -> SymBool -> m a -> m a -> m a
forall (u :: * -> *) a.
SymBranching u =>
MergingStrategy a -> SymBool -> u a -> u a -> u a
mrgIfWithStrategy MergingStrategy a
s SymBool
cond m a
l m a
r
  {-# INLINE mrgIfWithStrategy #-}
  mrgIfPropagatedStrategy :: forall a.
SymBool -> IdentityT m a -> IdentityT m a -> IdentityT m a
mrgIfPropagatedStrategy SymBool
cond (IdentityT m a
l) (IdentityT m a
r) =
    m a -> IdentityT m a
forall {k} (f :: k -> *) (a :: k). f a -> IdentityT f a
IdentityT (m a -> IdentityT m a) -> m a -> IdentityT m a
forall a b. (a -> b) -> a -> b
$ SymBool -> m a -> m a -> m a
forall a. SymBool -> m a -> m a -> m a
forall (u :: * -> *) a.
SymBranching u =>
SymBool -> u a -> u a -> u a
mrgIfPropagatedStrategy SymBool
cond m a
l m a
r
  {-# INLINE mrgIfPropagatedStrategy #-}

-- ContT
instance (SymBranching m, Mergeable r) => SimpleMergeable (ContT r m a) where
  mrgIte :: SymBool -> ContT r m a -> ContT r m a -> ContT r m a
mrgIte SymBool
cond (ContT (a -> m r) -> m r
l) (ContT (a -> m r) -> m r
r) = ((a -> m r) -> m r) -> ContT r m a
forall {k} (r :: k) (m :: k -> *) a.
((a -> m r) -> m r) -> ContT r m a
ContT (((a -> m r) -> m r) -> ContT r m a)
-> ((a -> m r) -> m r) -> ContT r m a
forall a b. (a -> b) -> a -> b
$ \a -> m r
c -> SymBool -> m r -> m r -> m r
forall (u :: * -> *) a.
(SymBranching u, Mergeable a) =>
SymBool -> u a -> u a -> u a
mrgIf SymBool
cond ((a -> m r) -> m r
l a -> m r
c) ((a -> m r) -> m r
r a -> m r
c)
  {-# INLINE mrgIte #-}

instance (SymBranching m, Mergeable r) => SimpleMergeable1 (ContT r m) where
  liftMrgIte :: forall a.
(SymBool -> a -> a -> a)
-> SymBool -> ContT r m a -> ContT r m a -> ContT r m a
liftMrgIte SymBool -> a -> a -> a
m = MergingStrategy a
-> SymBool -> ContT r m a -> ContT r m a -> ContT r m a
forall a.
MergingStrategy a
-> SymBool -> ContT r m a -> ContT r m a -> ContT r m a
forall (u :: * -> *) a.
SymBranching u =>
MergingStrategy a -> SymBool -> u a -> u a -> u a
mrgIfWithStrategy ((SymBool -> a -> a -> a) -> MergingStrategy a
forall a. (SymBool -> a -> a -> a) -> MergingStrategy a
SimpleStrategy SymBool -> a -> a -> a
m)
  {-# INLINE liftMrgIte #-}

instance (SymBranching m, Mergeable r) => SymBranching (ContT r m) where
  mrgIfWithStrategy :: forall a.
MergingStrategy a
-> SymBool -> ContT r m a -> ContT r m a -> ContT r m a
mrgIfWithStrategy MergingStrategy a
_ SymBool
cond (ContT (a -> m r) -> m r
l) (ContT (a -> m r) -> m r
r) =
    ((a -> m r) -> m r) -> ContT r m a
forall {k} (r :: k) (m :: k -> *) a.
((a -> m r) -> m r) -> ContT r m a
ContT (((a -> m r) -> m r) -> ContT r m a)
-> ((a -> m r) -> m r) -> ContT r m a
forall a b. (a -> b) -> a -> b
$ \a -> m r
c -> SymBool -> m r -> m r -> m r
forall (u :: * -> *) a.
(SymBranching u, Mergeable a) =>
SymBool -> u a -> u a -> u a
mrgIf SymBool
cond ((a -> m r) -> m r
l a -> m r
c) ((a -> m r) -> m r
r a -> m r
c)
  {-# INLINE mrgIfWithStrategy #-}
  mrgIfPropagatedStrategy :: forall a. SymBool -> ContT r m a -> ContT r m a -> ContT r m a
mrgIfPropagatedStrategy SymBool
cond (ContT (a -> m r) -> m r
l) (ContT (a -> m r) -> m r
r) =
    ((a -> m r) -> m r) -> ContT r m a
forall {k} (r :: k) (m :: k -> *) a.
((a -> m r) -> m r) -> ContT r m a
ContT (((a -> m r) -> m r) -> ContT r m a)
-> ((a -> m r) -> m r) -> ContT r m a
forall a b. (a -> b) -> a -> b
$ \a -> m r
c -> SymBool -> m r -> m r -> m r
forall a. SymBool -> m a -> m a -> m a
forall (u :: * -> *) a.
SymBranching u =>
SymBool -> u a -> u a -> u a
mrgIfPropagatedStrategy SymBool
cond ((a -> m r) -> m r
l a -> m r
c) ((a -> m r) -> m r
r a -> m r
c)
  {-# INLINE mrgIfPropagatedStrategy #-}

-- RWST
instance
  (Mergeable s, Mergeable w, Monoid w, Mergeable a, SymBranching m) =>
  SimpleMergeable (RWSLazy.RWST r w s m a)
  where
  mrgIte :: SymBool -> RWST r w s m a -> RWST r w s m a -> RWST r w s m a
mrgIte = SymBool -> RWST r w s m a -> RWST r w s m a -> RWST r w s m a
forall (u :: * -> *) a.
(SymBranching u, Mergeable a) =>
SymBool -> u a -> u a -> u a
mrgIf
  {-# INLINE mrgIte #-}

instance
  (Mergeable s, Mergeable w, Monoid w, SymBranching m) =>
  SimpleMergeable1 (RWSLazy.RWST r w s m)
  where
  liftMrgIte :: forall a.
(SymBool -> a -> a -> a)
-> SymBool -> RWST r w s m a -> RWST r w s m a -> RWST r w s m a
liftMrgIte SymBool -> a -> a -> a
m = MergingStrategy a
-> SymBool -> RWST r w s m a -> RWST r w s m a -> RWST r w s m a
forall a.
MergingStrategy a
-> SymBool -> RWST r w s m a -> RWST r w s m a -> RWST r w s m a
forall (u :: * -> *) a.
SymBranching u =>
MergingStrategy a -> SymBool -> u a -> u a -> u a
mrgIfWithStrategy ((SymBool -> a -> a -> a) -> MergingStrategy a
forall a. (SymBool -> a -> a -> a) -> MergingStrategy a
SimpleStrategy SymBool -> a -> a -> a
m)
  {-# INLINE liftMrgIte #-}

instance
  (Mergeable s, Mergeable w, Monoid w, SymBranching m) =>
  SymBranching (RWSLazy.RWST r w s m)
  where
  mrgIfWithStrategy :: forall a.
MergingStrategy a
-> SymBool -> RWST r w s m a -> RWST r w s m a -> RWST r w s m a
mrgIfWithStrategy MergingStrategy a
ms SymBool
cond (RWSLazy.RWST r -> s -> m (a, s, w)
t) (RWSLazy.RWST r -> s -> m (a, s, w)
f) =
    (r -> s -> m (a, s, w)) -> RWST r w s m a
forall r w s (m :: * -> *) a.
(r -> s -> m (a, s, w)) -> RWST r w s m a
RWSLazy.RWST ((r -> s -> m (a, s, w)) -> RWST r w s m a)
-> (r -> s -> m (a, s, w)) -> RWST r w s m a
forall a b. (a -> b) -> a -> b
$ \r
r s
s ->
      MergingStrategy (a, s, w)
-> SymBool -> m (a, s, w) -> m (a, s, w) -> m (a, s, w)
forall a. MergingStrategy a -> SymBool -> m a -> m a -> m a
forall (u :: * -> *) a.
SymBranching u =>
MergingStrategy a -> SymBool -> u a -> u a -> u a
mrgIfWithStrategy
        (MergingStrategy a
-> MergingStrategy s
-> MergingStrategy w
-> MergingStrategy (a, s, w)
forall a b c.
MergingStrategy a
-> MergingStrategy b
-> MergingStrategy c
-> MergingStrategy (a, b, c)
forall (u :: * -> * -> * -> *) a b c.
Mergeable3 u =>
MergingStrategy a
-> MergingStrategy b
-> MergingStrategy c
-> MergingStrategy (u a b c)
liftRootStrategy3 MergingStrategy a
ms MergingStrategy s
forall a. Mergeable a => MergingStrategy a
rootStrategy MergingStrategy w
forall a. Mergeable a => MergingStrategy a
rootStrategy)
        SymBool
cond
        (r -> s -> m (a, s, w)
t r
r s
s)
        (r -> s -> m (a, s, w)
f r
r s
s)
  {-# INLINE mrgIfWithStrategy #-}
  mrgIfPropagatedStrategy :: forall a.
SymBool -> RWST r w s m a -> RWST r w s m a -> RWST r w s m a
mrgIfPropagatedStrategy SymBool
cond (RWSLazy.RWST r -> s -> m (a, s, w)
t) (RWSLazy.RWST r -> s -> m (a, s, w)
f) =
    (r -> s -> m (a, s, w)) -> RWST r w s m a
forall r w s (m :: * -> *) a.
(r -> s -> m (a, s, w)) -> RWST r w s m a
RWSLazy.RWST ((r -> s -> m (a, s, w)) -> RWST r w s m a)
-> (r -> s -> m (a, s, w)) -> RWST r w s m a
forall a b. (a -> b) -> a -> b
$ \r
r s
s -> SymBool -> m (a, s, w) -> m (a, s, w) -> m (a, s, w)
forall a. SymBool -> m a -> m a -> m a
forall (u :: * -> *) a.
SymBranching u =>
SymBool -> u a -> u a -> u a
mrgIfPropagatedStrategy SymBool
cond (r -> s -> m (a, s, w)
t r
r s
s) (r -> s -> m (a, s, w)
f r
r s
s)
  {-# INLINE mrgIfPropagatedStrategy #-}

instance
  (Mergeable s, Mergeable w, Monoid w, Mergeable a, SymBranching m) =>
  SimpleMergeable (RWSStrict.RWST r w s m a)
  where
  mrgIte :: SymBool -> RWST r w s m a -> RWST r w s m a -> RWST r w s m a
mrgIte = SymBool -> RWST r w s m a -> RWST r w s m a -> RWST r w s m a
forall (u :: * -> *) a.
(SymBranching u, Mergeable a) =>
SymBool -> u a -> u a -> u a
mrgIf
  {-# INLINE mrgIte #-}

instance
  (Mergeable s, Mergeable w, Monoid w, SymBranching m) =>
  SimpleMergeable1 (RWSStrict.RWST r w s m)
  where
  liftMrgIte :: forall a.
(SymBool -> a -> a -> a)
-> SymBool -> RWST r w s m a -> RWST r w s m a -> RWST r w s m a
liftMrgIte SymBool -> a -> a -> a
m = MergingStrategy a
-> SymBool -> RWST r w s m a -> RWST r w s m a -> RWST r w s m a
forall a.
MergingStrategy a
-> SymBool -> RWST r w s m a -> RWST r w s m a -> RWST r w s m a
forall (u :: * -> *) a.
SymBranching u =>
MergingStrategy a -> SymBool -> u a -> u a -> u a
mrgIfWithStrategy ((SymBool -> a -> a -> a) -> MergingStrategy a
forall a. (SymBool -> a -> a -> a) -> MergingStrategy a
SimpleStrategy SymBool -> a -> a -> a
m)
  {-# INLINE liftMrgIte #-}

instance
  (Mergeable s, Mergeable w, Monoid w, SymBranching m) =>
  SymBranching (RWSStrict.RWST r w s m)
  where
  mrgIfWithStrategy :: forall a.
MergingStrategy a
-> SymBool -> RWST r w s m a -> RWST r w s m a -> RWST r w s m a
mrgIfWithStrategy MergingStrategy a
ms SymBool
cond (RWSStrict.RWST r -> s -> m (a, s, w)
t) (RWSStrict.RWST r -> s -> m (a, s, w)
f) =
    (r -> s -> m (a, s, w)) -> RWST r w s m a
forall r w s (m :: * -> *) a.
(r -> s -> m (a, s, w)) -> RWST r w s m a
RWSStrict.RWST ((r -> s -> m (a, s, w)) -> RWST r w s m a)
-> (r -> s -> m (a, s, w)) -> RWST r w s m a
forall a b. (a -> b) -> a -> b
$ \r
r s
s ->
      MergingStrategy (a, s, w)
-> SymBool -> m (a, s, w) -> m (a, s, w) -> m (a, s, w)
forall a. MergingStrategy a -> SymBool -> m a -> m a -> m a
forall (u :: * -> *) a.
SymBranching u =>
MergingStrategy a -> SymBool -> u a -> u a -> u a
mrgIfWithStrategy
        (MergingStrategy a
-> MergingStrategy s
-> MergingStrategy w
-> MergingStrategy (a, s, w)
forall a b c.
MergingStrategy a
-> MergingStrategy b
-> MergingStrategy c
-> MergingStrategy (a, b, c)
forall (u :: * -> * -> * -> *) a b c.
Mergeable3 u =>
MergingStrategy a
-> MergingStrategy b
-> MergingStrategy c
-> MergingStrategy (u a b c)
liftRootStrategy3 MergingStrategy a
ms MergingStrategy s
forall a. Mergeable a => MergingStrategy a
rootStrategy MergingStrategy w
forall a. Mergeable a => MergingStrategy a
rootStrategy)
        SymBool
cond
        (r -> s -> m (a, s, w)
t r
r s
s)
        (r -> s -> m (a, s, w)
f r
r s
s)
  {-# INLINE mrgIfWithStrategy #-}
  mrgIfPropagatedStrategy :: forall a.
SymBool -> RWST r w s m a -> RWST r w s m a -> RWST r w s m a
mrgIfPropagatedStrategy SymBool
cond (RWSStrict.RWST r -> s -> m (a, s, w)
t) (RWSStrict.RWST r -> s -> m (a, s, w)
f) =
    (r -> s -> m (a, s, w)) -> RWST r w s m a
forall r w s (m :: * -> *) a.
(r -> s -> m (a, s, w)) -> RWST r w s m a
RWSStrict.RWST ((r -> s -> m (a, s, w)) -> RWST r w s m a)
-> (r -> s -> m (a, s, w)) -> RWST r w s m a
forall a b. (a -> b) -> a -> b
$ \r
r s
s -> SymBool -> m (a, s, w) -> m (a, s, w) -> m (a, s, w)
forall a. SymBool -> m a -> m a -> m a
forall (u :: * -> *) a.
SymBranching u =>
SymBool -> u a -> u a -> u a
mrgIfPropagatedStrategy SymBool
cond (r -> s -> m (a, s, w)
t r
r s
s) (r -> s -> m (a, s, w)
f r
r s
s)
  {-# INLINE mrgIfPropagatedStrategy #-}

-- Product
deriving via
  (Default (Product l r a))
  instance
    (SimpleMergeable (l a), SimpleMergeable (r a)) =>
    SimpleMergeable (Product l r a)

deriving via
  (Default1 (Product l r))
  instance
    (SimpleMergeable1 l, SimpleMergeable1 r) => SimpleMergeable1 (Product l r)

-- Compose
deriving via
  (Default (Compose f g a))
  instance
    (SimpleMergeable (f (g a))) =>
    SimpleMergeable (Compose f g a)

instance
  (SimpleMergeable1 f, SimpleMergeable1 g) =>
  SimpleMergeable1 (Compose f g)
  where
  liftMrgIte :: forall a.
(SymBool -> a -> a -> a)
-> SymBool -> Compose f g a -> Compose f g a -> Compose f g a
liftMrgIte SymBool -> a -> a -> a
m SymBool
cond (Compose f (g a)
l) (Compose f (g a)
r) =
    f (g a) -> Compose f g a
forall {k} {k1} (f :: k -> *) (g :: k1 -> k) (a :: k1).
f (g a) -> Compose f g a
Compose (f (g a) -> Compose f g a) -> f (g a) -> Compose f g a
forall a b. (a -> b) -> a -> b
$ (SymBool -> g a -> g a -> g a)
-> SymBool -> f (g a) -> f (g a) -> f (g 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
liftMrgIte ((SymBool -> a -> a -> a) -> SymBool -> g a -> g a -> g a
forall a. (SymBool -> a -> a -> a) -> SymBool -> g a -> g a -> g a
forall (u :: * -> *) a.
SimpleMergeable1 u =>
(SymBool -> a -> a -> a) -> SymBool -> u a -> u a -> u a
liftMrgIte SymBool -> a -> a -> a
m) SymBool
cond f (g a)
l f (g a)
r

-- Const
deriving via
  (Default (Const a b))
  instance
    (SimpleMergeable a) => SimpleMergeable (Const a b)

deriving via
  (Default1 (Const a))
  instance
    (SimpleMergeable a) => SimpleMergeable1 (Const a)

-- Alt
deriving via
  (Default (Alt f a))
  instance
    (SimpleMergeable (f a)) => SimpleMergeable (Alt f a)

deriving via
  (Default1 (Alt f))
  instance
    (SimpleMergeable1 f) => SimpleMergeable1 (Alt f)

-- Ap
deriving via
  (Default (Ap f a))
  instance
    (SimpleMergeable (f a)) => SimpleMergeable (Ap f a)

deriving via
  (Default1 (Ap f))
  instance
    (SimpleMergeable1 f) => SimpleMergeable1 (Ap f)

-- Endo
instance (SimpleMergeable a) => SimpleMergeable (Endo a) where
  mrgIte :: SymBool -> Endo a -> Endo a -> Endo a
mrgIte = SymBool -> Endo a -> Endo a -> Endo a
forall (u :: * -> *) a.
(SimpleMergeable1 u, SimpleMergeable a) =>
SymBool -> u a -> u a -> u a
mrgIte1
  {-# INLINE mrgIte #-}

instance SimpleMergeable1 Endo where
  liftMrgIte :: forall a.
(SymBool -> a -> a -> a) -> SymBool -> Endo a -> Endo a -> Endo a
liftMrgIte SymBool -> a -> a -> a
m SymBool
cond (Endo a -> a
l) (Endo a -> a
r) = (a -> a) -> Endo a
forall a. (a -> a) -> Endo a
Endo ((a -> a) -> Endo a) -> (a -> a) -> Endo a
forall a b. (a -> b) -> a -> b
$ (SymBool -> a -> a -> a)
-> SymBool -> (a -> a) -> (a -> a) -> a -> a
forall a.
(SymBool -> a -> a -> a)
-> SymBool -> (a -> a) -> (a -> a) -> a -> a
forall (u :: * -> *) a.
SimpleMergeable1 u =>
(SymBool -> a -> a -> a) -> SymBool -> u a -> u a -> u a
liftMrgIte SymBool -> a -> a -> a
m SymBool
cond a -> a
l a -> a
r
  {-# INLINE liftMrgIte #-}

-- Generic
deriving via (Default (U1 p)) instance SimpleMergeable (U1 p)

deriving via (Default (V1 p)) instance SimpleMergeable (V1 p)

deriving via
  (Default (K1 i c p))
  instance
    (SimpleMergeable c) => SimpleMergeable (K1 i c p)

deriving via
  (Default (M1 i c f p))
  instance
    (SimpleMergeable (f p)) => SimpleMergeable (M1 i c f p)

deriving via
  (Default ((f :*: g) p))
  instance
    (SimpleMergeable (f p), SimpleMergeable (g p)) =>
    SimpleMergeable ((f :*: g) p)

deriving via
  (Default (Par1 p))
  instance
    (SimpleMergeable p) => SimpleMergeable (Par1 p)

deriving via
  (Default (Rec1 f p))
  instance
    (SimpleMergeable (f p)) => SimpleMergeable (Rec1 f p)

deriving via
  (Default ((f :.: g) p))
  instance
    (SimpleMergeable (f (g p))) => SimpleMergeable ((f :.: g) p)

#define SIMPLE_MERGEABLE_SIMPLE(symtype) \
instance SimpleMergeable symtype where \
  mrgIte = symIte; \
  {-# INLINE mrgIte #-}

#define SIMPLE_MERGEABLE_BV(symtype) \
instance (KnownNat n, 1 <= n) => SimpleMergeable (symtype n) where \
  mrgIte = symIte; \
  {-# INLINE mrgIte #-}

#define SIMPLE_MERGEABLE_FUN(cop, op) \
instance SimpleMergeable (op sa sb) where \
  mrgIte = symIte; \
  {-# INLINE mrgIte #-}

#if 1
SIMPLE_MERGEABLE_SIMPLE(SymInteger)
SIMPLE_MERGEABLE_SIMPLE(SymFPRoundingMode)
SIMPLE_MERGEABLE_SIMPLE(SymAlgReal)
SIMPLE_MERGEABLE_BV(SymIntN)
SIMPLE_MERGEABLE_BV(SymWordN)
SIMPLE_MERGEABLE_FUN((=->), (=~>))
SIMPLE_MERGEABLE_FUN((-->), (-~>))
#endif

instance SimpleMergeable (a --> b) where
  mrgIte :: SymBool -> (a --> b) -> (a --> b) -> a --> b
mrgIte = SymBool -> (a --> b) -> (a --> b) -> a --> b
forall v. ITEOp v => SymBool -> v -> v -> v
symIte
  {-# INLINE mrgIte #-}

instance (ValidFP eb sb) => SimpleMergeable (SymFP eb sb) where
  mrgIte :: SymBool -> SymFP eb sb -> SymFP eb sb -> SymFP eb sb
mrgIte = SymBool -> SymFP eb sb -> SymFP eb sb -> SymFP eb sb
forall v. ITEOp v => SymBool -> v -> v -> v
symIte
  {-# INLINE mrgIte #-}