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

-- {-# OPTIONS_GHC -ddump-splices -ddump-to-file -ddump-file-prefix=mergeable1 #-}

-- |
-- Module      :   Grisette.Internal.Internal.Impl.Core.Data.Class.Mergeable
-- 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.Mergeable () where

import Control.Exception
  ( ArithException
      ( Denormal,
        DivideByZero,
        LossOfPrecision,
        Overflow,
        RatioZeroDenominator,
        Underflow
      ),
  )
import Control.Monad.Cont (ContT (ContT))
import Control.Monad.Except (ExceptT)
import Control.Monad.Identity
  ( Identity,
    IdentityT (IdentityT, runIdentityT),
  )
import qualified Control.Monad.RWS.Lazy as RWSLazy
import qualified Control.Monad.RWS.Strict as RWSStrict
import Control.Monad.Reader (ReaderT (ReaderT, runReaderT))
import qualified Control.Monad.State.Lazy as StateLazy
import qualified Control.Monad.State.Strict as StateStrict
import Control.Monad.Trans.Maybe (MaybeT)
import qualified Control.Monad.Writer.Lazy as WriterLazy
import qualified Control.Monad.Writer.Strict as WriterStrict
import qualified Data.ByteString as B
import Data.Functor.Compose (Compose (Compose, getCompose))
import Data.Functor.Const (Const)
import Data.Functor.Product (Product)
import Data.Functor.Sum (Sum)
import Data.Int (Int16, Int32, Int64, Int8)
import Data.Monoid (Alt, Ap, Endo (Endo, appEndo))
import qualified Data.Monoid as Monoid
import Data.Ord (Down)
import Data.Ratio (Ratio)
import qualified Data.Text as T
import Data.Typeable (Proxy, Typeable)
import Data.Word (Word16, Word32, Word64, Word8)
import GHC.TypeNats (KnownNat, type (+), type (<=))
import Generics.Deriving
  ( Default (Default),
    Default1 (Default1),
    K1 (K1),
    M1 (M1),
    Par1 (Par1),
    Rec1 (Rec1),
    U1,
    V1,
    (:.:) (Comp1),
    type (:*:),
    type (:+:),
  )
import Grisette.Internal.Core.Control.Exception
  ( AssertionError,
    VerificationConditions,
  )
import Grisette.Internal.Core.Data.Class.BitCast (bitCastOrCanonical)
import Grisette.Internal.Core.Data.Class.ITEOp (ITEOp (symIte))
import Grisette.Internal.Internal.Decl.Core.Data.Class.Mergeable
  ( Mergeable (rootStrategy),
    Mergeable1 (liftRootStrategy),
    Mergeable2 (liftRootStrategy2),
    Mergeable3 (liftRootStrategy3),
    MergingStrategy (NoStrategy, SimpleStrategy, SortedStrategy),
    StrategyList (StrategyList),
    buildStrategyList,
    rootStrategy1,
    wrapStrategy,
  )
import Grisette.Internal.SymPrim.AlgReal (AlgReal, AlgRealPoly, RealPoint)
import Grisette.Internal.SymPrim.BV
  ( IntN,
    WordN,
  )
import Grisette.Internal.SymPrim.FP
  ( FP,
    FPRoundingMode,
    NotRepresentableFPError,
    ValidFP,
    withValidFPProofs,
  )
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.SymPrim.TabularFun (type (=->))
import Grisette.Internal.TH.Derivation.Derive (derive)
import Unsafe.Coerce (unsafeCoerce)

#define CONCRETE_ORD_MERGEABLE(type) \
instance Mergeable type where \
  rootStrategy = \
    let sub = SimpleStrategy $ \_ t _ -> t \
     in SortedStrategy id $ const sub

#define CONCRETE_ORD_MERGEABLE_BV(type) \
instance (KnownNat n, 1 <= n) => Mergeable (type n) where \
  rootStrategy = \
    let sub = SimpleStrategy $ \_ t _ -> t \
     in SortedStrategy id $ const sub

#if 1
CONCRETE_ORD_MERGEABLE(Bool)
CONCRETE_ORD_MERGEABLE(Integer)
CONCRETE_ORD_MERGEABLE(Char)
CONCRETE_ORD_MERGEABLE(Int)
CONCRETE_ORD_MERGEABLE(Int8)
CONCRETE_ORD_MERGEABLE(Int16)
CONCRETE_ORD_MERGEABLE(Int32)
CONCRETE_ORD_MERGEABLE(Int64)
CONCRETE_ORD_MERGEABLE(Word)
CONCRETE_ORD_MERGEABLE(Word8)
CONCRETE_ORD_MERGEABLE(Word16)
CONCRETE_ORD_MERGEABLE(Word32)
CONCRETE_ORD_MERGEABLE(Word64)
CONCRETE_ORD_MERGEABLE(Float)
CONCRETE_ORD_MERGEABLE(Double)
CONCRETE_ORD_MERGEABLE(B.ByteString)
CONCRETE_ORD_MERGEABLE(T.Text)
CONCRETE_ORD_MERGEABLE(FPRoundingMode)
CONCRETE_ORD_MERGEABLE(Monoid.All)
CONCRETE_ORD_MERGEABLE(Monoid.Any)
CONCRETE_ORD_MERGEABLE_BV(WordN)
CONCRETE_ORD_MERGEABLE_BV(IntN)
#endif

instance Mergeable (Proxy a) where
  rootStrategy :: MergingStrategy (Proxy a)
rootStrategy = (SymBool -> Proxy a -> Proxy a -> Proxy a)
-> MergingStrategy (Proxy a)
forall a. (SymBool -> a -> a -> a) -> MergingStrategy a
SimpleStrategy ((SymBool -> Proxy a -> Proxy a -> Proxy a)
 -> MergingStrategy (Proxy a))
-> (SymBool -> Proxy a -> Proxy a -> Proxy a)
-> MergingStrategy (Proxy a)
forall a b. (a -> b) -> a -> b
$ \SymBool
_ Proxy a
t Proxy a
_ -> Proxy a
t

instance Mergeable1 Proxy where
  liftRootStrategy :: forall a. MergingStrategy a -> MergingStrategy (Proxy a)
liftRootStrategy MergingStrategy a
_ = (SymBool -> Proxy a -> Proxy a -> Proxy a)
-> MergingStrategy (Proxy a)
forall a. (SymBool -> a -> a -> a) -> MergingStrategy a
SimpleStrategy ((SymBool -> Proxy a -> Proxy a -> Proxy a)
 -> MergingStrategy (Proxy a))
-> (SymBool -> Proxy a -> Proxy a -> Proxy a)
-> MergingStrategy (Proxy a)
forall a b. (a -> b) -> a -> b
$ \SymBool
_ Proxy a
t Proxy a
_ -> Proxy a
t
  {-# INLINE liftRootStrategy #-}

instance (Integral a, Typeable a, Show a) => Mergeable (Ratio a) where
  rootStrategy :: MergingStrategy (Ratio a)
rootStrategy =
    let sub :: MergingStrategy a
sub = (SymBool -> a -> a -> a) -> MergingStrategy a
forall a. (SymBool -> a -> a -> a) -> MergingStrategy a
SimpleStrategy ((SymBool -> a -> a -> a) -> MergingStrategy a)
-> (SymBool -> a -> a -> a) -> MergingStrategy a
forall a b. (a -> b) -> a -> b
$ \SymBool
_ a
t a
_ -> a
t
     in (Ratio a -> Ratio a)
-> (Ratio a -> MergingStrategy (Ratio a))
-> MergingStrategy (Ratio a)
forall idx a.
(Ord idx, Typeable idx, Show idx) =>
(a -> idx) -> (idx -> MergingStrategy a) -> MergingStrategy a
SortedStrategy Ratio a -> Ratio a
forall a. a -> a
id ((Ratio a -> MergingStrategy (Ratio a))
 -> MergingStrategy (Ratio a))
-> (Ratio a -> MergingStrategy (Ratio a))
-> MergingStrategy (Ratio a)
forall a b. (a -> b) -> a -> b
$ MergingStrategy (Ratio a) -> Ratio a -> MergingStrategy (Ratio a)
forall a b. a -> b -> a
const MergingStrategy (Ratio a)
forall {a}. MergingStrategy a
sub

instance (ValidFP eb sb) => Mergeable (FP eb sb) where
  rootStrategy :: MergingStrategy (FP eb sb)
rootStrategy =
    let sub :: MergingStrategy a
sub = (SymBool -> a -> a -> a) -> MergingStrategy a
forall a. (SymBool -> a -> a -> a) -> MergingStrategy a
SimpleStrategy ((SymBool -> a -> a -> a) -> MergingStrategy a)
-> (SymBool -> a -> a -> a) -> MergingStrategy a
forall a b. (a -> b) -> a -> b
$ \SymBool
_ a
t a
_ -> a
t
     in forall (eb :: Nat) (sb :: Nat) r.
ValidFP eb sb =>
((KnownNat (eb + sb), BVIsNonZero (eb + sb), 1 <= (eb + sb),
  1 <= eb, 1 <= sb) =>
 r)
-> r
withValidFPProofs @eb @sb
          (((KnownNat (eb + sb), BVIsNonZero (eb + sb), 1 <= (eb + sb),
   1 <= eb, 1 <= sb) =>
  MergingStrategy (FP eb sb))
 -> MergingStrategy (FP eb sb))
-> ((KnownNat (eb + sb), BVIsNonZero (eb + sb), 1 <= (eb + sb),
     1 <= eb, 1 <= sb) =>
    MergingStrategy (FP eb sb))
-> MergingStrategy (FP eb sb)
forall a b. (a -> b) -> a -> b
$ (FP eb sb -> WordN (eb + sb))
-> (WordN (eb + sb) -> MergingStrategy (FP eb sb))
-> MergingStrategy (FP eb sb)
forall idx a.
(Ord idx, Typeable idx, Show idx) =>
(a -> idx) -> (idx -> MergingStrategy a) -> MergingStrategy a
SortedStrategy
            (\FP eb sb
fp -> (FP eb sb -> WordN (eb + sb)
forall from to. BitCastOrCanonical from to => from -> to
bitCastOrCanonical FP eb sb
fp :: WordN (eb + sb)))
          ((WordN (eb + sb) -> MergingStrategy (FP eb sb))
 -> MergingStrategy (FP eb sb))
-> (WordN (eb + sb) -> MergingStrategy (FP eb sb))
-> MergingStrategy (FP eb sb)
forall a b. (a -> b) -> a -> b
$ MergingStrategy (FP eb sb)
-> WordN (eb + sb) -> MergingStrategy (FP eb sb)
forall a b. a -> b -> a
const MergingStrategy (FP eb sb)
forall {a}. MergingStrategy a
sub

instance Mergeable (a =-> b) where
  rootStrategy :: MergingStrategy (a =-> b)
rootStrategy = MergingStrategy (a =-> b)
forall {a}. MergingStrategy a
NoStrategy

instance Mergeable (a --> b) where
  rootStrategy :: MergingStrategy (a --> b)
rootStrategy = (SymBool -> (a --> b) -> (a --> b) -> a --> b)
-> MergingStrategy (a --> b)
forall a. (SymBool -> a -> a -> a) -> MergingStrategy a
SimpleStrategy SymBool -> (a --> b) -> (a --> b) -> a --> b
forall v. ITEOp v => SymBool -> v -> v -> v
symIte

#define MERGEABLE_SIMPLE(symtype) \
instance Mergeable symtype where \
  rootStrategy = SimpleStrategy symIte

#define MERGEABLE_BV(symtype) \
instance (KnownNat n, 1 <= n) => Mergeable (symtype n) where \
  rootStrategy = SimpleStrategy symIte

#define MERGEABLE_FUN(cop, op, consop) \
instance Mergeable (op sa sb) where \
  rootStrategy = SimpleStrategy symIte

#if 1
MERGEABLE_SIMPLE(SymInteger)
MERGEABLE_SIMPLE(SymFPRoundingMode)
MERGEABLE_SIMPLE(SymAlgReal)
MERGEABLE_BV(SymIntN)
MERGEABLE_BV(SymWordN)
MERGEABLE_FUN((=->), (=~>), SymTabularFun)
MERGEABLE_FUN((-->), (-~>), SymGeneralFun)
#endif

instance (ValidFP eb sb) => Mergeable (SymFP eb sb) where
  rootStrategy :: MergingStrategy (SymFP eb sb)
rootStrategy = (SymBool -> SymFP eb sb -> SymFP eb sb -> SymFP eb sb)
-> MergingStrategy (SymFP eb sb)
forall a. (SymBool -> a -> a -> a) -> MergingStrategy a
SimpleStrategy SymBool -> SymFP eb sb -> SymFP eb sb -> SymFP eb sb
forall v. ITEOp v => SymBool -> v -> v -> v
symIte

-- function
instance (Mergeable b) => Mergeable (a -> b) where
  rootStrategy :: MergingStrategy (a -> b)
rootStrategy = case forall a. Mergeable a => MergingStrategy a
rootStrategy @b of
    SimpleStrategy SymBool -> b -> b -> b
m -> (SymBool -> (a -> b) -> (a -> b) -> a -> b)
-> MergingStrategy (a -> b)
forall a. (SymBool -> a -> a -> a) -> MergingStrategy a
SimpleStrategy ((SymBool -> (a -> b) -> (a -> b) -> a -> b)
 -> MergingStrategy (a -> b))
-> (SymBool -> (a -> b) -> (a -> b) -> a -> b)
-> MergingStrategy (a -> b)
forall a b. (a -> b) -> a -> b
$ \SymBool
cond a -> b
t a -> b
f a
v -> SymBool -> b -> b -> b
m SymBool
cond (a -> b
t a
v) (a -> b
f a
v)
    MergingStrategy b
_ -> MergingStrategy (a -> b)
forall {a}. MergingStrategy a
NoStrategy
  {-# INLINE rootStrategy #-}

instance Mergeable1 ((->) a) where
  liftRootStrategy :: forall a. MergingStrategy a -> MergingStrategy (a -> a)
liftRootStrategy MergingStrategy a
ms = case MergingStrategy a
ms of
    SimpleStrategy SymBool -> a -> a -> a
m -> (SymBool -> (a -> a) -> (a -> a) -> a -> a)
-> MergingStrategy (a -> a)
forall a. (SymBool -> a -> a -> a) -> MergingStrategy a
SimpleStrategy ((SymBool -> (a -> a) -> (a -> a) -> a -> a)
 -> MergingStrategy (a -> a))
-> (SymBool -> (a -> a) -> (a -> a) -> a -> a)
-> MergingStrategy (a -> a)
forall a b. (a -> b) -> a -> b
$ \SymBool
cond a -> a
t a -> a
f a
v -> SymBool -> a -> a -> a
m SymBool
cond (a -> a
t a
v) (a -> a
f a
v)
    MergingStrategy a
_ -> MergingStrategy (a -> a)
forall {a}. MergingStrategy a
NoStrategy
  {-# INLINE liftRootStrategy #-}

instance Mergeable2 ((->)) where
  liftRootStrategy2 :: forall a b.
MergingStrategy a -> MergingStrategy b -> MergingStrategy (a -> b)
liftRootStrategy2 MergingStrategy a
_ MergingStrategy b
ms = case MergingStrategy b
ms of
    SimpleStrategy SymBool -> b -> b -> b
m -> (SymBool -> (a -> b) -> (a -> b) -> a -> b)
-> MergingStrategy (a -> b)
forall a. (SymBool -> a -> a -> a) -> MergingStrategy a
SimpleStrategy ((SymBool -> (a -> b) -> (a -> b) -> a -> b)
 -> MergingStrategy (a -> b))
-> (SymBool -> (a -> b) -> (a -> b) -> a -> b)
-> MergingStrategy (a -> b)
forall a b. (a -> b) -> a -> b
$ \SymBool
cond a -> b
t a -> b
f a
v -> SymBool -> b -> b -> b
m SymBool
cond (a -> b
t a
v) (a -> b
f a
v)
    MergingStrategy b
_ -> MergingStrategy (a -> b)
forall {a}. MergingStrategy a
NoStrategy
  {-# INLINE liftRootStrategy2 #-}

-- List

instance (Mergeable a) => Mergeable [a] where
  rootStrategy :: MergingStrategy [a]
rootStrategy = case MergingStrategy a
forall a. Mergeable a => MergingStrategy a
rootStrategy :: MergingStrategy a of
    SimpleStrategy SymBool -> a -> a -> a
m ->
      ([a] -> Int) -> (Int -> MergingStrategy [a]) -> MergingStrategy [a]
forall idx a.
(Ord idx, Typeable idx, Show idx) =>
(a -> idx) -> (idx -> MergingStrategy a) -> MergingStrategy a
SortedStrategy [a] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length ((Int -> MergingStrategy [a]) -> MergingStrategy [a])
-> (Int -> MergingStrategy [a]) -> MergingStrategy [a]
forall a b. (a -> b) -> a -> b
$ \Int
_ ->
        (SymBool -> [a] -> [a] -> [a]) -> MergingStrategy [a]
forall a. (SymBool -> a -> a -> a) -> MergingStrategy a
SimpleStrategy ((SymBool -> [a] -> [a] -> [a]) -> MergingStrategy [a])
-> (SymBool -> [a] -> [a] -> [a]) -> MergingStrategy [a]
forall a b. (a -> b) -> a -> b
$ \SymBool
cond -> (a -> a -> a) -> [a] -> [a] -> [a]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith (SymBool -> a -> a -> a
m SymBool
cond)
    MergingStrategy a
NoStrategy ->
      ([a] -> Int) -> (Int -> MergingStrategy [a]) -> MergingStrategy [a]
forall idx a.
(Ord idx, Typeable idx, Show idx) =>
(a -> idx) -> (idx -> MergingStrategy a) -> MergingStrategy a
SortedStrategy [a] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length ((Int -> MergingStrategy [a]) -> MergingStrategy [a])
-> (Int -> MergingStrategy [a]) -> MergingStrategy [a]
forall a b. (a -> b) -> a -> b
$ MergingStrategy [a] -> Int -> MergingStrategy [a]
forall a b. a -> b -> a
const MergingStrategy [a]
forall {a}. MergingStrategy a
NoStrategy
    MergingStrategy a
_ -> ([a] -> Int) -> (Int -> MergingStrategy [a]) -> MergingStrategy [a]
forall idx a.
(Ord idx, Typeable idx, Show idx) =>
(a -> idx) -> (idx -> MergingStrategy a) -> MergingStrategy a
SortedStrategy [a] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length ((Int -> MergingStrategy [a]) -> MergingStrategy [a])
-> (Int -> MergingStrategy [a]) -> MergingStrategy [a]
forall a b. (a -> b) -> a -> b
$ \Int
_ ->
      ([a] -> StrategyList [])
-> (StrategyList [] -> MergingStrategy [a]) -> MergingStrategy [a]
forall idx a.
(Ord idx, Typeable idx, Show idx) =>
(a -> idx) -> (idx -> MergingStrategy a) -> MergingStrategy a
SortedStrategy (MergingStrategy a -> [a] -> StrategyList []
forall a (container :: * -> *).
Functor container =>
MergingStrategy a -> container a -> StrategyList container
buildStrategyList MergingStrategy a
forall a. Mergeable a => MergingStrategy a
rootStrategy) ((StrategyList [] -> MergingStrategy [a]) -> MergingStrategy [a])
-> (StrategyList [] -> MergingStrategy [a]) -> MergingStrategy [a]
forall a b. (a -> b) -> a -> b
$
        \(StrategyList [[DynamicSortedIdx]]
_ [MergingStrategy a]
strategies) ->
          let [MergingStrategy a]
s :: [MergingStrategy a] = [MergingStrategy a] -> [MergingStrategy a]
forall a b. a -> b
unsafeCoerce [MergingStrategy a]
strategies
              allSimple :: Bool
allSimple = (MergingStrategy a -> Bool) -> [MergingStrategy a] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (\case SimpleStrategy SymBool -> a -> a -> a
_ -> Bool
True; MergingStrategy a
_ -> Bool
False) [MergingStrategy a]
s
           in if Bool
allSimple
                then (SymBool -> [a] -> [a] -> [a]) -> MergingStrategy [a]
forall a. (SymBool -> a -> a -> a) -> MergingStrategy a
SimpleStrategy ((SymBool -> [a] -> [a] -> [a]) -> MergingStrategy [a])
-> (SymBool -> [a] -> [a] -> [a]) -> MergingStrategy [a]
forall a b. (a -> b) -> a -> b
$ \SymBool
cond [a]
l [a]
r ->
                  ( \case
                      (SimpleStrategy SymBool -> a -> a -> a
f, a
l1, a
r1) -> SymBool -> a -> a -> a
f SymBool
cond a
l1 a
r1
                      (MergingStrategy a, a, a)
_ -> [Char] -> a
forall a. HasCallStack => [Char] -> a
error [Char]
"impossible"
                  )
                    ((MergingStrategy a, a, a) -> a)
-> [(MergingStrategy a, a, a)] -> [a]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [MergingStrategy a] -> [a] -> [a] -> [(MergingStrategy a, a, a)]
forall a b c. [a] -> [b] -> [c] -> [(a, b, c)]
zip3 [MergingStrategy a]
s [a]
l [a]
r
                else MergingStrategy [a]
forall {a}. MergingStrategy a
NoStrategy
  {-# INLINE rootStrategy #-}

instance Mergeable1 [] where
  liftRootStrategy :: forall a. MergingStrategy a -> MergingStrategy [a]
liftRootStrategy (MergingStrategy a
ms :: MergingStrategy a) = case MergingStrategy a
ms of
    SimpleStrategy SymBool -> a -> a -> a
m ->
      ([a] -> Int) -> (Int -> MergingStrategy [a]) -> MergingStrategy [a]
forall idx a.
(Ord idx, Typeable idx, Show idx) =>
(a -> idx) -> (idx -> MergingStrategy a) -> MergingStrategy a
SortedStrategy [a] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length ((Int -> MergingStrategy [a]) -> MergingStrategy [a])
-> (Int -> MergingStrategy [a]) -> MergingStrategy [a]
forall a b. (a -> b) -> a -> b
$ \Int
_ ->
        (SymBool -> [a] -> [a] -> [a]) -> MergingStrategy [a]
forall a. (SymBool -> a -> a -> a) -> MergingStrategy a
SimpleStrategy ((SymBool -> [a] -> [a] -> [a]) -> MergingStrategy [a])
-> (SymBool -> [a] -> [a] -> [a]) -> MergingStrategy [a]
forall a b. (a -> b) -> a -> b
$ \SymBool
cond -> (a -> a -> a) -> [a] -> [a] -> [a]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith (SymBool -> a -> a -> a
m SymBool
cond)
    MergingStrategy a
NoStrategy ->
      ([a] -> Int) -> (Int -> MergingStrategy [a]) -> MergingStrategy [a]
forall idx a.
(Ord idx, Typeable idx, Show idx) =>
(a -> idx) -> (idx -> MergingStrategy a) -> MergingStrategy a
SortedStrategy [a] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length ((Int -> MergingStrategy [a]) -> MergingStrategy [a])
-> (Int -> MergingStrategy [a]) -> MergingStrategy [a]
forall a b. (a -> b) -> a -> b
$ MergingStrategy [a] -> Int -> MergingStrategy [a]
forall a b. a -> b -> a
const MergingStrategy [a]
forall {a}. MergingStrategy a
NoStrategy
    MergingStrategy a
_ -> ([a] -> Int) -> (Int -> MergingStrategy [a]) -> MergingStrategy [a]
forall idx a.
(Ord idx, Typeable idx, Show idx) =>
(a -> idx) -> (idx -> MergingStrategy a) -> MergingStrategy a
SortedStrategy [a] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length ((Int -> MergingStrategy [a]) -> MergingStrategy [a])
-> (Int -> MergingStrategy [a]) -> MergingStrategy [a]
forall a b. (a -> b) -> a -> b
$ \Int
_ ->
      ([a] -> StrategyList [])
-> (StrategyList [] -> MergingStrategy [a]) -> MergingStrategy [a]
forall idx a.
(Ord idx, Typeable idx, Show idx) =>
(a -> idx) -> (idx -> MergingStrategy a) -> MergingStrategy a
SortedStrategy (MergingStrategy a -> [a] -> StrategyList []
forall a (container :: * -> *).
Functor container =>
MergingStrategy a -> container a -> StrategyList container
buildStrategyList MergingStrategy a
ms) ((StrategyList [] -> MergingStrategy [a]) -> MergingStrategy [a])
-> (StrategyList [] -> MergingStrategy [a]) -> MergingStrategy [a]
forall a b. (a -> b) -> a -> b
$ \(StrategyList [[DynamicSortedIdx]]
_ [MergingStrategy a]
strategies) ->
        let [MergingStrategy a]
s :: [MergingStrategy a] = [MergingStrategy a] -> [MergingStrategy a]
forall a b. a -> b
unsafeCoerce [MergingStrategy a]
strategies
            allSimple :: Bool
allSimple = (MergingStrategy a -> Bool) -> [MergingStrategy a] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (\case SimpleStrategy SymBool -> a -> a -> a
_ -> Bool
True; MergingStrategy a
_ -> Bool
False) [MergingStrategy a]
s
         in if Bool
allSimple
              then (SymBool -> [a] -> [a] -> [a]) -> MergingStrategy [a]
forall a. (SymBool -> a -> a -> a) -> MergingStrategy a
SimpleStrategy ((SymBool -> [a] -> [a] -> [a]) -> MergingStrategy [a])
-> (SymBool -> [a] -> [a] -> [a]) -> MergingStrategy [a]
forall a b. (a -> b) -> a -> b
$ \SymBool
cond [a]
l [a]
r ->
                ( \case
                    (SimpleStrategy SymBool -> a -> a -> a
f, a
l1, a
r1) -> SymBool -> a -> a -> a
f SymBool
cond a
l1 a
r1
                    (MergingStrategy a, a, a)
_ -> [Char] -> a
forall a. HasCallStack => [Char] -> a
error [Char]
"impossible"
                )
                  ((MergingStrategy a, a, a) -> a)
-> [(MergingStrategy a, a, a)] -> [a]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [MergingStrategy a] -> [a] -> [a] -> [(MergingStrategy a, a, a)]
forall a b c. [a] -> [b] -> [c] -> [(a, b, c)]
zip3 [MergingStrategy a]
s [a]
l [a]
r
              else MergingStrategy [a]
forall {a}. MergingStrategy a
NoStrategy
  {-# INLINE liftRootStrategy #-}

instance Mergeable () where
  rootStrategy :: MergingStrategy ()
rootStrategy = (SymBool -> () -> () -> ()) -> MergingStrategy ()
forall a. (SymBool -> a -> a -> a) -> MergingStrategy a
SimpleStrategy ((SymBool -> () -> () -> ()) -> MergingStrategy ())
-> (SymBool -> () -> () -> ()) -> MergingStrategy ()
forall a b. (a -> b) -> a -> b
$ \SymBool
_ ()
t ()
_ -> ()
t

derive
  [ ''Either,
    ''(,)
  ]
  [''Mergeable, ''Mergeable1, ''Mergeable2]

derive
  [ ''(,,),
    ''(,,,),
    ''(,,,,),
    ''(,,,,,),
    ''(,,,,,,),
    ''(,,,,,,,),
    ''(,,,,,,,,),
    ''(,,,,,,,,,),
    ''(,,,,,,,,,,),
    ''(,,,,,,,,,,,),
    ''(,,,,,,,,,,,,),
    ''(,,,,,,,,,,,,,),
    ''(,,,,,,,,,,,,,,)
  ]
  [''Mergeable, ''Mergeable1, ''Mergeable2, ''Mergeable3]

derive
  [ ''Maybe,
    ''Identity,
    ''Monoid.Dual,
    ''Monoid.Sum,
    ''Monoid.Product,
    ''Monoid.First,
    ''Monoid.Last,
    ''Down,
    ''MaybeT,
    ''ExceptT,
    ''WriterLazy.WriterT,
    ''WriterStrict.WriterT,
    ''StateLazy.StateT,
    ''StateStrict.StateT
  ]
  [''Mergeable, ''Mergeable1]

derive
  [ ''AssertionError,
    ''VerificationConditions,
    ''NotRepresentableFPError,
    ''AlgRealPoly,
    ''RealPoint,
    ''AlgReal
  ]
  [''Mergeable]

-- Reader -- separately implemented as we don't need Mergeable s
instance
  (Mergeable a, Mergeable1 m) =>
  Mergeable (ReaderT s m a)
  where
  rootStrategy :: MergingStrategy (ReaderT s m a)
rootStrategy = MergingStrategy (ReaderT s m a)
forall a (u :: * -> *).
(Mergeable a, Mergeable1 u) =>
MergingStrategy (u a)
rootStrategy1
  {-# INLINE rootStrategy #-}

instance (Mergeable1 m) => Mergeable1 (ReaderT s m) where
  liftRootStrategy :: forall a. MergingStrategy a -> MergingStrategy (ReaderT s m a)
liftRootStrategy MergingStrategy a
m =
    MergingStrategy (s -> m a)
-> ((s -> m a) -> ReaderT s m a)
-> (ReaderT s m a -> s -> m a)
-> MergingStrategy (ReaderT s m a)
forall a b.
MergingStrategy a -> (a -> b) -> (b -> a) -> MergingStrategy b
wrapStrategy
      (MergingStrategy (m a) -> MergingStrategy (s -> m a)
forall a. MergingStrategy a -> MergingStrategy (s -> a)
forall (u :: * -> *) a.
Mergeable1 u =>
MergingStrategy a -> MergingStrategy (u a)
liftRootStrategy (MergingStrategy a -> MergingStrategy (m a)
forall a. MergingStrategy a -> MergingStrategy (m a)
forall (u :: * -> *) a.
Mergeable1 u =>
MergingStrategy a -> MergingStrategy (u a)
liftRootStrategy MergingStrategy a
m))
      (s -> m a) -> ReaderT s m a
forall r (m :: * -> *) a. (r -> m a) -> ReaderT r m a
ReaderT
      ReaderT s m a -> s -> m a
forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
runReaderT
  {-# INLINE liftRootStrategy #-}

-- IdentityT
instance (Mergeable1 m, Mergeable a) => Mergeable (IdentityT m a) where
  rootStrategy :: MergingStrategy (IdentityT m a)
rootStrategy = MergingStrategy (IdentityT m a)
forall a (u :: * -> *).
(Mergeable a, Mergeable1 u) =>
MergingStrategy (u a)
rootStrategy1
  {-# INLINE rootStrategy #-}

instance (Mergeable1 m) => Mergeable1 (IdentityT m) where
  liftRootStrategy :: forall a. MergingStrategy a -> MergingStrategy (IdentityT m a)
liftRootStrategy MergingStrategy a
m = MergingStrategy (m a)
-> (m a -> IdentityT m a)
-> (IdentityT m a -> m a)
-> MergingStrategy (IdentityT m a)
forall a b.
MergingStrategy a -> (a -> b) -> (b -> a) -> MergingStrategy b
wrapStrategy (MergingStrategy a -> MergingStrategy (m a)
forall a. MergingStrategy a -> MergingStrategy (m a)
forall (u :: * -> *) a.
Mergeable1 u =>
MergingStrategy a -> MergingStrategy (u a)
liftRootStrategy MergingStrategy a
m) m a -> IdentityT m a
forall {k} (f :: k -> *) (a :: k). f a -> IdentityT f a
IdentityT IdentityT m a -> m a
forall {k} (f :: k -> *) (a :: k). IdentityT f a -> f a
runIdentityT
  {-# INLINE liftRootStrategy #-}

-- ContT -- separately implemented as we don't need Mergeable a
instance (Mergeable1 m, Mergeable r) => Mergeable (ContT r m a) where
  rootStrategy :: MergingStrategy (ContT r m a)
rootStrategy =
    MergingStrategy ((a -> m r) -> m r)
-> (((a -> m r) -> m r) -> ContT r m a)
-> (ContT r m a -> (a -> m r) -> m r)
-> MergingStrategy (ContT r m a)
forall a b.
MergingStrategy a -> (a -> b) -> (b -> a) -> MergingStrategy b
wrapStrategy
      (MergingStrategy (m r) -> MergingStrategy ((a -> m r) -> m r)
forall a. MergingStrategy a -> MergingStrategy ((a -> m r) -> a)
forall (u :: * -> *) a.
Mergeable1 u =>
MergingStrategy a -> MergingStrategy (u a)
liftRootStrategy MergingStrategy (m r)
forall a (u :: * -> *).
(Mergeable a, Mergeable1 u) =>
MergingStrategy (u a)
rootStrategy1)
      ((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
      (\(ContT (a -> m r) -> m r
v) -> (a -> m r) -> m r
v)
  {-# INLINE rootStrategy #-}

instance (Mergeable1 m, Mergeable r) => Mergeable1 (ContT r m) where
  liftRootStrategy :: forall a. MergingStrategy a -> MergingStrategy (ContT r m a)
liftRootStrategy MergingStrategy a
_ =
    MergingStrategy ((a -> m r) -> m r)
-> (((a -> m r) -> m r) -> ContT r m a)
-> (ContT r m a -> (a -> m r) -> m r)
-> MergingStrategy (ContT r m a)
forall a b.
MergingStrategy a -> (a -> b) -> (b -> a) -> MergingStrategy b
wrapStrategy
      (MergingStrategy (m r) -> MergingStrategy ((a -> m r) -> m r)
forall a. MergingStrategy a -> MergingStrategy ((a -> m r) -> a)
forall (u :: * -> *) a.
Mergeable1 u =>
MergingStrategy a -> MergingStrategy (u a)
liftRootStrategy MergingStrategy (m r)
forall a (u :: * -> *).
(Mergeable a, Mergeable1 u) =>
MergingStrategy (u a)
rootStrategy1)
      ((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
      (\(ContT (a -> m r) -> m r
v) -> (a -> m r) -> m r
v)
  {-# INLINE liftRootStrategy #-}

-- RWS -- separately implemented as we don't need Mergeable r
instance
  (Mergeable s, Mergeable w, Mergeable a, Mergeable1 m) =>
  Mergeable (RWSLazy.RWST r w s m a)
  where
  rootStrategy :: MergingStrategy (RWST r w s m a)
rootStrategy = MergingStrategy (RWST r w s m a)
forall a (u :: * -> *).
(Mergeable a, Mergeable1 u) =>
MergingStrategy (u a)
rootStrategy1
  {-# INLINE rootStrategy #-}

instance
  (Mergeable s, Mergeable w, Mergeable1 m) =>
  Mergeable1 (RWSLazy.RWST r w s m)
  where
  liftRootStrategy :: forall a. MergingStrategy a -> MergingStrategy (RWST r w s m a)
liftRootStrategy MergingStrategy a
m =
    MergingStrategy (r -> s -> m (a, s, w))
-> ((r -> s -> m (a, s, w)) -> RWST r w s m a)
-> (RWST r w s m a -> r -> s -> m (a, s, w))
-> MergingStrategy (RWST r w s m a)
forall a b.
MergingStrategy a -> (a -> b) -> (b -> a) -> MergingStrategy b
wrapStrategy
      ( MergingStrategy (s -> m (a, s, w))
-> MergingStrategy (r -> s -> m (a, s, w))
forall a. MergingStrategy a -> MergingStrategy (r -> a)
forall (u :: * -> *) a.
Mergeable1 u =>
MergingStrategy a -> MergingStrategy (u a)
liftRootStrategy (MergingStrategy (s -> m (a, s, w))
 -> MergingStrategy (r -> s -> m (a, s, w)))
-> (MergingStrategy (a, s, w)
    -> MergingStrategy (s -> m (a, s, w)))
-> MergingStrategy (a, s, w)
-> MergingStrategy (r -> s -> m (a, s, w))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MergingStrategy (m (a, s, w)) -> MergingStrategy (s -> m (a, s, w))
forall a. MergingStrategy a -> MergingStrategy (s -> a)
forall (u :: * -> *) a.
Mergeable1 u =>
MergingStrategy a -> MergingStrategy (u a)
liftRootStrategy (MergingStrategy (m (a, s, w))
 -> MergingStrategy (s -> m (a, s, w)))
-> (MergingStrategy (a, s, w) -> MergingStrategy (m (a, s, w)))
-> MergingStrategy (a, s, w)
-> MergingStrategy (s -> m (a, s, w))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MergingStrategy (a, s, w) -> MergingStrategy (m (a, s, w))
forall a. MergingStrategy a -> MergingStrategy (m a)
forall (u :: * -> *) a.
Mergeable1 u =>
MergingStrategy a -> MergingStrategy (u a)
liftRootStrategy (MergingStrategy (a, s, w)
 -> MergingStrategy (r -> s -> m (a, s, w)))
-> MergingStrategy (a, s, w)
-> MergingStrategy (r -> s -> m (a, s, w))
forall a b. (a -> b) -> a -> b
$
          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
m MergingStrategy s
forall a. Mergeable a => MergingStrategy a
rootStrategy MergingStrategy w
forall a. Mergeable a => MergingStrategy a
rootStrategy
      )
      (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
      (\(RWSLazy.RWST r -> s -> m (a, s, w)
rws) -> r -> s -> m (a, s, w)
rws)
  {-# INLINE liftRootStrategy #-}

instance
  (Mergeable s, Mergeable w, Mergeable a, Mergeable1 m) =>
  Mergeable (RWSStrict.RWST r w s m a)
  where
  rootStrategy :: MergingStrategy (RWST r w s m a)
rootStrategy = MergingStrategy (RWST r w s m a)
forall a (u :: * -> *).
(Mergeable a, Mergeable1 u) =>
MergingStrategy (u a)
rootStrategy1
  {-# INLINE rootStrategy #-}

instance
  (Mergeable s, Mergeable w, Mergeable1 m) =>
  Mergeable1 (RWSStrict.RWST r w s m)
  where
  liftRootStrategy :: forall a. MergingStrategy a -> MergingStrategy (RWST r w s m a)
liftRootStrategy MergingStrategy a
m =
    MergingStrategy (r -> s -> m (a, s, w))
-> ((r -> s -> m (a, s, w)) -> RWST r w s m a)
-> (RWST r w s m a -> r -> s -> m (a, s, w))
-> MergingStrategy (RWST r w s m a)
forall a b.
MergingStrategy a -> (a -> b) -> (b -> a) -> MergingStrategy b
wrapStrategy
      ( MergingStrategy (s -> m (a, s, w))
-> MergingStrategy (r -> s -> m (a, s, w))
forall a. MergingStrategy a -> MergingStrategy (r -> a)
forall (u :: * -> *) a.
Mergeable1 u =>
MergingStrategy a -> MergingStrategy (u a)
liftRootStrategy (MergingStrategy (s -> m (a, s, w))
 -> MergingStrategy (r -> s -> m (a, s, w)))
-> (MergingStrategy (a, s, w)
    -> MergingStrategy (s -> m (a, s, w)))
-> MergingStrategy (a, s, w)
-> MergingStrategy (r -> s -> m (a, s, w))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MergingStrategy (m (a, s, w)) -> MergingStrategy (s -> m (a, s, w))
forall a. MergingStrategy a -> MergingStrategy (s -> a)
forall (u :: * -> *) a.
Mergeable1 u =>
MergingStrategy a -> MergingStrategy (u a)
liftRootStrategy (MergingStrategy (m (a, s, w))
 -> MergingStrategy (s -> m (a, s, w)))
-> (MergingStrategy (a, s, w) -> MergingStrategy (m (a, s, w)))
-> MergingStrategy (a, s, w)
-> MergingStrategy (s -> m (a, s, w))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MergingStrategy (a, s, w) -> MergingStrategy (m (a, s, w))
forall a. MergingStrategy a -> MergingStrategy (m a)
forall (u :: * -> *) a.
Mergeable1 u =>
MergingStrategy a -> MergingStrategy (u a)
liftRootStrategy (MergingStrategy (a, s, w)
 -> MergingStrategy (r -> s -> m (a, s, w)))
-> MergingStrategy (a, s, w)
-> MergingStrategy (r -> s -> m (a, s, w))
forall a b. (a -> b) -> a -> b
$
          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
m MergingStrategy s
forall a. Mergeable a => MergingStrategy a
rootStrategy MergingStrategy w
forall a. Mergeable a => MergingStrategy a
rootStrategy
      )
      (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
      (\(RWSStrict.RWST r -> s -> m (a, s, w)
rws) -> r -> s -> m (a, s, w)
rws)
  {-# INLINE liftRootStrategy #-}

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

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

-- Sum
deriving via
  (Default (Sum l r a))
  instance
    (Mergeable (l a), Mergeable (r a)) => Mergeable (Sum l r a)

deriving via
  (Default1 (Sum l r))
  instance
    (Mergeable1 l, Mergeable1 r) => Mergeable1 (Sum l r)

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

instance (Mergeable1 f, Mergeable1 g) => Mergeable1 (Compose f g) where
  liftRootStrategy :: forall a. MergingStrategy a -> MergingStrategy (Compose f g a)
liftRootStrategy MergingStrategy a
s =
    MergingStrategy (f (g a))
-> (f (g a) -> Compose f g a)
-> (Compose f g a -> f (g a))
-> MergingStrategy (Compose f g a)
forall a b.
MergingStrategy a -> (a -> b) -> (b -> a) -> MergingStrategy b
wrapStrategy (MergingStrategy (g a) -> MergingStrategy (f (g a))
forall a. MergingStrategy a -> MergingStrategy (f a)
forall (u :: * -> *) a.
Mergeable1 u =>
MergingStrategy a -> MergingStrategy (u a)
liftRootStrategy (MergingStrategy a -> MergingStrategy (g a)
forall a. MergingStrategy a -> MergingStrategy (g a)
forall (u :: * -> *) a.
Mergeable1 u =>
MergingStrategy a -> MergingStrategy (u a)
liftRootStrategy MergingStrategy a
s)) 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 Compose f g a -> f (g a)
forall {k1} {k2} (f :: k1 -> *) (g :: k2 -> k1) (a :: k2).
Compose f g a -> f (g a)
getCompose
  {-# INLINE liftRootStrategy #-}

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

deriving via
  (Default1 (Const a))
  instance
    (Mergeable a) => Mergeable1 (Const a)

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

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

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

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

-- Endo
instance (Mergeable a) => Mergeable (Endo a) where
  rootStrategy :: MergingStrategy (Endo a)
rootStrategy = MergingStrategy (Endo a)
forall a (u :: * -> *).
(Mergeable a, Mergeable1 u) =>
MergingStrategy (u a)
rootStrategy1
  {-# INLINE rootStrategy #-}

instance Mergeable1 Endo where
  liftRootStrategy :: forall a. MergingStrategy a -> MergingStrategy (Endo a)
liftRootStrategy MergingStrategy a
strategy =
    MergingStrategy (a -> a)
-> ((a -> a) -> Endo a)
-> (Endo a -> a -> a)
-> MergingStrategy (Endo a)
forall a b.
MergingStrategy a -> (a -> b) -> (b -> a) -> MergingStrategy b
wrapStrategy (MergingStrategy a -> MergingStrategy (a -> a)
forall a. MergingStrategy a -> MergingStrategy (a -> a)
forall (u :: * -> *) a.
Mergeable1 u =>
MergingStrategy a -> MergingStrategy (u a)
liftRootStrategy MergingStrategy a
strategy) (a -> a) -> Endo a
forall a. (a -> a) -> Endo a
Endo Endo a -> a -> a
forall a. Endo a -> a -> a
appEndo

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

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

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

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

deriving via
  (Default ((f :+: g) p))
  instance
    (Mergeable (f p), Mergeable (g p)) => Mergeable ((f :+: g) p)

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

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

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

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

-- Exceptions
instance Mergeable ArithException where
  rootStrategy :: MergingStrategy ArithException
rootStrategy =
    (ArithException -> Int)
-> (Int -> MergingStrategy ArithException)
-> MergingStrategy ArithException
forall idx a.
(Ord idx, Typeable idx, Show idx) =>
(a -> idx) -> (idx -> MergingStrategy a) -> MergingStrategy a
SortedStrategy
      ( \case
          ArithException
Overflow -> Int
0 :: Int
          ArithException
Underflow -> Int
1 :: Int
          ArithException
LossOfPrecision -> Int
2 :: Int
          ArithException
DivideByZero -> Int
3 :: Int
          ArithException
Denormal -> Int
4 :: Int
          ArithException
RatioZeroDenominator -> Int
5 :: Int
      )
      (MergingStrategy ArithException
-> Int -> MergingStrategy ArithException
forall a b. a -> b -> a
const (MergingStrategy ArithException
 -> Int -> MergingStrategy ArithException)
-> MergingStrategy ArithException
-> Int
-> MergingStrategy ArithException
forall a b. (a -> b) -> a -> b
$ (SymBool -> ArithException -> ArithException -> ArithException)
-> MergingStrategy ArithException
forall a. (SymBool -> a -> a -> a) -> MergingStrategy a
SimpleStrategy ((SymBool -> ArithException -> ArithException -> ArithException)
 -> MergingStrategy ArithException)
-> (SymBool -> ArithException -> ArithException -> ArithException)
-> MergingStrategy ArithException
forall a b. (a -> b) -> a -> b
$ \SymBool
_ ArithException
l ArithException
_ -> ArithException
l)