{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE DeriveLift #-}
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}

module Grisette.Internal.Core.Data.Class.AsKey
  ( KeyEq (..),
    KeyOrd (..),
    KeyHashable (..),
    KeyEq1 (..),
    KeyOrd1 (..),
    KeyHashable1 (..),
    AsKey (..),
    AsKey1 (..),
    shouldUseAsKeyError,
    shouldUseAsKeyHasSymbolicVersionError,
    shouldUseSymbolicVersionError,
  )
where

import Control.DeepSeq (NFData, NFData1)
import Control.Monad.Identity (Identity)
import qualified Data.Binary as Binary
import Data.Bits (Bits, FiniteBits)
import qualified Data.Bytes.Serial as Serial
import Data.Functor.Classes
  ( Eq1 (liftEq),
    Ord1 (liftCompare),
    Show1,
    compare1,
    eq1,
  )
import Data.Hashable (Hashable (hashWithSalt))
import Data.Hashable.Lifted (Hashable1 (liftHashWithSalt), hashWithSalt1)
import Data.Proxy (Proxy (Proxy))
import qualified Data.Serialize as Cereal
import Data.String (IsString)
import GHC.Stack (HasCallStack)
import GHC.TypeLits (KnownNat, type (<=))
import Grisette.Internal.Core.Data.Class.BitCast
  ( BitCast (bitCast),
    BitCastCanonical (bitCastCanonicalValue),
  )
import Grisette.Internal.Core.Data.Class.BitVector
  ( BV (bv, bvConcat, bvExt, bvSelect, bvSext, bvZext),
  )
import Grisette.Internal.Core.Data.Class.Concrete (Concrete)
import Grisette.Internal.Core.Data.Class.Function
  ( Apply (FunType, apply),
    Function ((#)),
  )
import Grisette.Internal.Core.Data.Class.IEEEFP
  ( IEEEFPConstants
      ( fpMaxNormalized,
        fpMaxSubnormal,
        fpMinNormalized,
        fpMinSubnormal,
        fpNaN,
        fpNegativeInfinite,
        fpNegativeZero,
        fpPositiveInfinite,
        fpPositiveZero
      ),
    IEEEFPConvertible (fromFPOr, toFP),
    IEEEFPOp
      ( fpAbs,
        fpMaximum,
        fpMaximumNumber,
        fpMinimum,
        fpMinimumNumber,
        fpNeg,
        fpRem
      ),
    IEEEFPRoundingMode (rna, rne, rtn, rtp, rtz),
    IEEEFPRoundingOp
      ( fpAdd,
        fpDiv,
        fpFMA,
        fpMul,
        fpRoundToIntegral,
        fpSqrt,
        fpSub
      ),
    IEEEFPToAlgReal (fpToAlgReal),
  )
import Grisette.Internal.Core.Data.Class.SignConversion
  ( SignConversion (toSigned, toUnsigned),
  )
import Grisette.Internal.SymPrim.AlgReal (AlgReal)
import Grisette.Internal.SymPrim.BV (IntN, WordN)
import Grisette.Internal.SymPrim.FP (FP, ValidFP)
import Grisette.Internal.SymPrim.Prim.Internal.Term (ConRep (ConType))
import Language.Haskell.TH.Syntax (Lift)

-- | Type class for identity equality for terms.
class KeyEq a where
  keyEq :: a -> a -> Bool

infix 4 `keyEq`

instance (KnownNat n, 1 <= n) => KeyEq (WordN n) where
  keyEq :: WordN n -> WordN n -> Bool
keyEq = WordN n -> WordN n -> Bool
forall a. Eq a => a -> a -> Bool
(==)

instance (KnownNat n, 1 <= n) => KeyEq (IntN n) where
  keyEq :: IntN n -> IntN n -> Bool
keyEq = IntN n -> IntN n -> Bool
forall a. Eq a => a -> a -> Bool
(==)

instance KeyEq Integer where
  keyEq :: Integer -> Integer -> Bool
keyEq = Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
(==)

instance KeyEq Bool where
  keyEq :: Bool -> Bool -> Bool
keyEq = Bool -> Bool -> Bool
forall a. Eq a => a -> a -> Bool
(==)

instance KeyEq AlgReal where
  keyEq :: AlgReal -> AlgReal -> Bool
keyEq = AlgReal -> AlgReal -> Bool
forall a. Eq a => a -> a -> Bool
(==)

instance (ValidFP a b) => KeyEq (FP a b) where
  keyEq :: FP a b -> FP a b -> Bool
keyEq = FP a b -> FP a b -> Bool
forall a. Eq a => a -> a -> Bool
(==)

instance (Eq a) => KeyEq (Identity a) where
  keyEq :: Identity a -> Identity a -> Bool
keyEq = Identity a -> Identity a -> Bool
forall a. Eq a => a -> a -> Bool
(==)

-- | Type class for comparing terms based on their identity.
class (KeyEq a) => KeyOrd a where
  keyCompare :: a -> a -> Ordering

infix 4 `keyCompare`

-- | Type class for hashing terms based on their identity.
class (KeyEq a) => KeyHashable a where
  keyHashWithSalt :: Int -> a -> Int

instance (KnownNat n, 1 <= n) => KeyHashable (WordN n) where
  keyHashWithSalt :: Int -> WordN n -> Int
keyHashWithSalt = Int -> WordN n -> Int
forall a. Hashable a => Int -> a -> Int
hashWithSalt

instance (KnownNat n, 1 <= n) => KeyHashable (IntN n) where
  keyHashWithSalt :: Int -> IntN n -> Int
keyHashWithSalt = Int -> IntN n -> Int
forall a. Hashable a => Int -> a -> Int
hashWithSalt

instance KeyHashable Integer where
  keyHashWithSalt :: Int -> Integer -> Int
keyHashWithSalt = Int -> Integer -> Int
forall a. Hashable a => Int -> a -> Int
hashWithSalt

instance KeyHashable Bool where
  keyHashWithSalt :: Int -> Bool -> Int
keyHashWithSalt = Int -> Bool -> Int
forall a. Hashable a => Int -> a -> Int
hashWithSalt

instance KeyHashable AlgReal where
  keyHashWithSalt :: Int -> AlgReal -> Int
keyHashWithSalt = Int -> AlgReal -> Int
forall a. Hashable a => Int -> a -> Int
hashWithSalt

instance (ValidFP a b) => KeyHashable (FP a b) where
  keyHashWithSalt :: Int -> FP a b -> Int
keyHashWithSalt = Int -> FP a b -> Int
forall a. Hashable a => Int -> a -> Int
hashWithSalt

instance (Eq a, Hashable a) => KeyHashable (Identity a) where
  keyHashWithSalt :: Int -> Identity a -> Int
keyHashWithSalt = Int -> Identity a -> Int
forall a. Hashable a => Int -> a -> Int
hashWithSalt

class KeyEq1 f where
  liftKeyEq :: (a -> b -> Bool) -> f a -> f b -> Bool

class (KeyEq1 f) => KeyOrd1 f where
  liftKeyCompare :: (a -> b -> Ordering) -> f a -> f b -> Ordering

class (KeyEq1 f) => KeyHashable1 f where
  liftKeyHashWithSalt :: (Int -> a -> Int) -> Int -> f a -> Int

infixl 0 `keyHashWithSalt`

-- | Use a term as a key with identity equality.
--
-- For example, @t'AsKey' t'Grisette.SymPrim.SymBool'@ uses the term identity
-- for t'Grisette.SymPrim.SymBool'.
newtype AsKey a = AsKey {forall a. AsKey a -> a
getAsKey :: a}
  deriving newtype
    ( Get (AsKey a)
[AsKey a] -> Put
AsKey a -> Put
(AsKey a -> Put)
-> Get (AsKey a) -> ([AsKey a] -> Put) -> Binary (AsKey a)
forall a. Binary a => Get (AsKey a)
forall a. Binary a => [AsKey a] -> Put
forall a. Binary a => AsKey a -> Put
forall t. (t -> Put) -> Get t -> ([t] -> Put) -> Binary t
$cput :: forall a. Binary a => AsKey a -> Put
put :: AsKey a -> Put
$cget :: forall a. Binary a => Get (AsKey a)
get :: Get (AsKey a)
$cputList :: forall a. Binary a => [AsKey a] -> Put
putList :: [AsKey a] -> Put
Binary.Binary,
      Get (AsKey a)
Putter (AsKey a)
Putter (AsKey a) -> Get (AsKey a) -> Serialize (AsKey a)
forall a. Serialize a => Get (AsKey a)
forall a. Serialize a => Putter (AsKey a)
forall t. Putter t -> Get t -> Serialize t
$cput :: forall a. Serialize a => Putter (AsKey a)
put :: Putter (AsKey a)
$cget :: forall a. Serialize a => Get (AsKey a)
get :: Get (AsKey a)
Cereal.Serialize,
      AsKey a -> ()
(AsKey a -> ()) -> NFData (AsKey a)
forall a. NFData a => AsKey a -> ()
forall a. (a -> ()) -> NFData a
$crnf :: forall a. NFData a => AsKey a -> ()
rnf :: AsKey a -> ()
NFData,
      String -> AsKey a
(String -> AsKey a) -> IsString (AsKey a)
forall a. IsString a => String -> AsKey a
forall a. (String -> a) -> IsString a
$cfromString :: forall a. IsString a => String -> AsKey a
fromString :: String -> AsKey a
IsString,
      Int -> AsKey a -> ShowS
[AsKey a] -> ShowS
AsKey a -> String
(Int -> AsKey a -> ShowS)
-> (AsKey a -> String) -> ([AsKey a] -> ShowS) -> Show (AsKey a)
forall a. Show a => Int -> AsKey a -> ShowS
forall a. Show a => [AsKey a] -> ShowS
forall a. Show a => AsKey a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall a. Show a => Int -> AsKey a -> ShowS
showsPrec :: Int -> AsKey a -> ShowS
$cshow :: forall a. Show a => AsKey a -> String
show :: AsKey a -> String
$cshowList :: forall a. Show a => [AsKey a] -> ShowS
showList :: [AsKey a] -> ShowS
Show,
      Integer -> AsKey a
AsKey a -> AsKey a
AsKey a -> AsKey a -> AsKey a
(AsKey a -> AsKey a -> AsKey a)
-> (AsKey a -> AsKey a -> AsKey a)
-> (AsKey a -> AsKey a -> AsKey a)
-> (AsKey a -> AsKey a)
-> (AsKey a -> AsKey a)
-> (AsKey a -> AsKey a)
-> (Integer -> AsKey a)
-> Num (AsKey a)
forall a. Num a => Integer -> AsKey a
forall a. Num a => AsKey a -> AsKey a
forall a. Num a => AsKey a -> AsKey a -> AsKey a
forall a.
(a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (Integer -> a)
-> Num a
$c+ :: forall a. Num a => AsKey a -> AsKey a -> AsKey a
+ :: AsKey a -> AsKey a -> AsKey a
$c- :: forall a. Num a => AsKey a -> AsKey a -> AsKey a
- :: AsKey a -> AsKey a -> AsKey a
$c* :: forall a. Num a => AsKey a -> AsKey a -> AsKey a
* :: AsKey a -> AsKey a -> AsKey a
$cnegate :: forall a. Num a => AsKey a -> AsKey a
negate :: AsKey a -> AsKey a
$cabs :: forall a. Num a => AsKey a -> AsKey a
abs :: AsKey a -> AsKey a
$csignum :: forall a. Num a => AsKey a -> AsKey a
signum :: AsKey a -> AsKey a
$cfromInteger :: forall a. Num a => Integer -> AsKey a
fromInteger :: Integer -> AsKey a
Num,
      Eq (AsKey a)
AsKey a
Eq (AsKey a) =>
(AsKey a -> AsKey a -> AsKey a)
-> (AsKey a -> AsKey a -> AsKey a)
-> (AsKey a -> AsKey a -> AsKey a)
-> (AsKey a -> AsKey a)
-> (AsKey a -> Int -> AsKey a)
-> (AsKey a -> Int -> AsKey a)
-> AsKey a
-> (Int -> AsKey a)
-> (AsKey a -> Int -> AsKey a)
-> (AsKey a -> Int -> AsKey a)
-> (AsKey a -> Int -> AsKey a)
-> (AsKey a -> Int -> Bool)
-> (AsKey a -> Maybe Int)
-> (AsKey a -> Int)
-> (AsKey a -> Bool)
-> (AsKey a -> Int -> AsKey a)
-> (AsKey a -> Int -> AsKey a)
-> (AsKey a -> Int -> AsKey a)
-> (AsKey a -> Int -> AsKey a)
-> (AsKey a -> Int -> AsKey a)
-> (AsKey a -> Int -> AsKey a)
-> (AsKey a -> Int)
-> Bits (AsKey a)
Int -> AsKey a
AsKey a -> Bool
AsKey a -> Int
AsKey a -> Maybe Int
AsKey a -> AsKey a
AsKey a -> Int -> Bool
AsKey a -> Int -> AsKey a
AsKey a -> AsKey a -> AsKey a
forall a.
Eq a =>
(a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a)
-> (a -> Int -> a)
-> (a -> Int -> a)
-> a
-> (Int -> a)
-> (a -> Int -> a)
-> (a -> Int -> a)
-> (a -> Int -> a)
-> (a -> Int -> Bool)
-> (a -> Maybe Int)
-> (a -> Int)
-> (a -> Bool)
-> (a -> Int -> a)
-> (a -> Int -> a)
-> (a -> Int -> a)
-> (a -> Int -> a)
-> (a -> Int -> a)
-> (a -> Int -> a)
-> (a -> Int)
-> Bits a
forall a. (KeyEq a, Bits a) => Eq (AsKey a)
forall a. (KeyEq a, Bits a) => AsKey a
forall a. (KeyEq a, Bits a) => Int -> AsKey a
forall a. (KeyEq a, Bits a) => AsKey a -> Bool
forall a. (KeyEq a, Bits a) => AsKey a -> Int
forall a. (KeyEq a, Bits a) => AsKey a -> Maybe Int
forall a. (KeyEq a, Bits a) => AsKey a -> AsKey a
forall a. (KeyEq a, Bits a) => AsKey a -> Int -> Bool
forall a. (KeyEq a, Bits a) => AsKey a -> Int -> AsKey a
forall a. (KeyEq a, Bits a) => AsKey a -> AsKey a -> AsKey a
$c.&. :: forall a. (KeyEq a, Bits a) => AsKey a -> AsKey a -> AsKey a
.&. :: AsKey a -> AsKey a -> AsKey a
$c.|. :: forall a. (KeyEq a, Bits a) => AsKey a -> AsKey a -> AsKey a
.|. :: AsKey a -> AsKey a -> AsKey a
$cxor :: forall a. (KeyEq a, Bits a) => AsKey a -> AsKey a -> AsKey a
xor :: AsKey a -> AsKey a -> AsKey a
$ccomplement :: forall a. (KeyEq a, Bits a) => AsKey a -> AsKey a
complement :: AsKey a -> AsKey a
$cshift :: forall a. (KeyEq a, Bits a) => AsKey a -> Int -> AsKey a
shift :: AsKey a -> Int -> AsKey a
$crotate :: forall a. (KeyEq a, Bits a) => AsKey a -> Int -> AsKey a
rotate :: AsKey a -> Int -> AsKey a
$czeroBits :: forall a. (KeyEq a, Bits a) => AsKey a
zeroBits :: AsKey a
$cbit :: forall a. (KeyEq a, Bits a) => Int -> AsKey a
bit :: Int -> AsKey a
$csetBit :: forall a. (KeyEq a, Bits a) => AsKey a -> Int -> AsKey a
setBit :: AsKey a -> Int -> AsKey a
$cclearBit :: forall a. (KeyEq a, Bits a) => AsKey a -> Int -> AsKey a
clearBit :: AsKey a -> Int -> AsKey a
$ccomplementBit :: forall a. (KeyEq a, Bits a) => AsKey a -> Int -> AsKey a
complementBit :: AsKey a -> Int -> AsKey a
$ctestBit :: forall a. (KeyEq a, Bits a) => AsKey a -> Int -> Bool
testBit :: AsKey a -> Int -> Bool
$cbitSizeMaybe :: forall a. (KeyEq a, Bits a) => AsKey a -> Maybe Int
bitSizeMaybe :: AsKey a -> Maybe Int
$cbitSize :: forall a. (KeyEq a, Bits a) => AsKey a -> Int
bitSize :: AsKey a -> Int
$cisSigned :: forall a. (KeyEq a, Bits a) => AsKey a -> Bool
isSigned :: AsKey a -> Bool
$cshiftL :: forall a. (KeyEq a, Bits a) => AsKey a -> Int -> AsKey a
shiftL :: AsKey a -> Int -> AsKey a
$cunsafeShiftL :: forall a. (KeyEq a, Bits a) => AsKey a -> Int -> AsKey a
unsafeShiftL :: AsKey a -> Int -> AsKey a
$cshiftR :: forall a. (KeyEq a, Bits a) => AsKey a -> Int -> AsKey a
shiftR :: AsKey a -> Int -> AsKey a
$cunsafeShiftR :: forall a. (KeyEq a, Bits a) => AsKey a -> Int -> AsKey a
unsafeShiftR :: AsKey a -> Int -> AsKey a
$crotateL :: forall a. (KeyEq a, Bits a) => AsKey a -> Int -> AsKey a
rotateL :: AsKey a -> Int -> AsKey a
$crotateR :: forall a. (KeyEq a, Bits a) => AsKey a -> Int -> AsKey a
rotateR :: AsKey a -> Int -> AsKey a
$cpopCount :: forall a. (KeyEq a, Bits a) => AsKey a -> Int
popCount :: AsKey a -> Int
Bits,
      Bits (AsKey a)
Bits (AsKey a) =>
(AsKey a -> Int)
-> (AsKey a -> Int) -> (AsKey a -> Int) -> FiniteBits (AsKey a)
AsKey a -> Int
forall b.
Bits b =>
(b -> Int) -> (b -> Int) -> (b -> Int) -> FiniteBits b
forall a. (KeyEq a, FiniteBits a) => Bits (AsKey a)
forall a. (KeyEq a, FiniteBits a) => AsKey a -> Int
$cfiniteBitSize :: forall a. (KeyEq a, FiniteBits a) => AsKey a -> Int
finiteBitSize :: AsKey a -> Int
$ccountLeadingZeros :: forall a. (KeyEq a, FiniteBits a) => AsKey a -> Int
countLeadingZeros :: AsKey a -> Int
$ccountTrailingZeros :: forall a. (KeyEq a, FiniteBits a) => AsKey a -> Int
countTrailingZeros :: AsKey a -> Int
FiniteBits,
      Int -> AsKey a
AsKey a -> Int
AsKey a -> [AsKey a]
AsKey a -> AsKey a
AsKey a -> AsKey a -> [AsKey a]
AsKey a -> AsKey a -> AsKey a -> [AsKey a]
(AsKey a -> AsKey a)
-> (AsKey a -> AsKey a)
-> (Int -> AsKey a)
-> (AsKey a -> Int)
-> (AsKey a -> [AsKey a])
-> (AsKey a -> AsKey a -> [AsKey a])
-> (AsKey a -> AsKey a -> [AsKey a])
-> (AsKey a -> AsKey a -> AsKey a -> [AsKey a])
-> Enum (AsKey a)
forall a. Enum a => Int -> AsKey a
forall a. Enum a => AsKey a -> Int
forall a. Enum a => AsKey a -> [AsKey a]
forall a. Enum a => AsKey a -> AsKey a
forall a. Enum a => AsKey a -> AsKey a -> [AsKey a]
forall a. Enum a => AsKey a -> AsKey a -> AsKey a -> [AsKey a]
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
$csucc :: forall a. Enum a => AsKey a -> AsKey a
succ :: AsKey a -> AsKey a
$cpred :: forall a. Enum a => AsKey a -> AsKey a
pred :: AsKey a -> AsKey a
$ctoEnum :: forall a. Enum a => Int -> AsKey a
toEnum :: Int -> AsKey a
$cfromEnum :: forall a. Enum a => AsKey a -> Int
fromEnum :: AsKey a -> Int
$cenumFrom :: forall a. Enum a => AsKey a -> [AsKey a]
enumFrom :: AsKey a -> [AsKey a]
$cenumFromThen :: forall a. Enum a => AsKey a -> AsKey a -> [AsKey a]
enumFromThen :: AsKey a -> AsKey a -> [AsKey a]
$cenumFromTo :: forall a. Enum a => AsKey a -> AsKey a -> [AsKey a]
enumFromTo :: AsKey a -> AsKey a -> [AsKey a]
$cenumFromThenTo :: forall a. Enum a => AsKey a -> AsKey a -> AsKey a -> [AsKey a]
enumFromThenTo :: AsKey a -> AsKey a -> AsKey a -> [AsKey a]
Enum,
      AsKey a
AsKey a -> AsKey a -> Bounded (AsKey a)
forall a. a -> a -> Bounded a
forall a. Bounded a => AsKey a
$cminBound :: forall a. Bounded a => AsKey a
minBound :: AsKey a
$cmaxBound :: forall a. Bounded a => AsKey a
maxBound :: AsKey a
Bounded,
      Num (AsKey a)
Num (AsKey a) =>
(AsKey a -> AsKey a -> AsKey a)
-> (AsKey a -> AsKey a)
-> (Rational -> AsKey a)
-> Fractional (AsKey a)
Rational -> AsKey a
AsKey a -> AsKey a
AsKey a -> AsKey a -> AsKey a
forall a. Fractional a => Num (AsKey a)
forall a. Fractional a => Rational -> AsKey a
forall a. Fractional a => AsKey a -> AsKey a
forall a. Fractional a => AsKey a -> AsKey a -> AsKey a
forall a.
Num a =>
(a -> a -> a) -> (a -> a) -> (Rational -> a) -> Fractional a
$c/ :: forall a. Fractional a => AsKey a -> AsKey a -> AsKey a
/ :: AsKey a -> AsKey a -> AsKey a
$crecip :: forall a. Fractional a => AsKey a -> AsKey a
recip :: AsKey a -> AsKey a
$cfromRational :: forall a. Fractional a => Rational -> AsKey a
fromRational :: Rational -> AsKey a
Fractional,
      Fractional (AsKey a)
AsKey a
Fractional (AsKey a) =>
AsKey a
-> (AsKey a -> AsKey a)
-> (AsKey a -> AsKey a)
-> (AsKey a -> AsKey a)
-> (AsKey a -> AsKey a -> AsKey a)
-> (AsKey a -> AsKey a -> AsKey a)
-> (AsKey a -> AsKey a)
-> (AsKey a -> AsKey a)
-> (AsKey a -> AsKey a)
-> (AsKey a -> AsKey a)
-> (AsKey a -> AsKey a)
-> (AsKey a -> AsKey a)
-> (AsKey a -> AsKey a)
-> (AsKey a -> AsKey a)
-> (AsKey a -> AsKey a)
-> (AsKey a -> AsKey a)
-> (AsKey a -> AsKey a)
-> (AsKey a -> AsKey a)
-> (AsKey a -> AsKey a)
-> (AsKey a -> AsKey a)
-> (AsKey a -> AsKey a)
-> (AsKey a -> AsKey a)
-> Floating (AsKey a)
AsKey a -> AsKey a
AsKey a -> AsKey a -> AsKey a
forall a. Floating a => Fractional (AsKey a)
forall a. Floating a => AsKey a
forall a. Floating a => AsKey a -> AsKey a
forall a. Floating a => AsKey a -> AsKey a -> AsKey a
forall a.
Fractional a =>
a
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> Floating a
$cpi :: forall a. Floating a => AsKey a
pi :: AsKey a
$cexp :: forall a. Floating a => AsKey a -> AsKey a
exp :: AsKey a -> AsKey a
$clog :: forall a. Floating a => AsKey a -> AsKey a
log :: AsKey a -> AsKey a
$csqrt :: forall a. Floating a => AsKey a -> AsKey a
sqrt :: AsKey a -> AsKey a
$c** :: forall a. Floating a => AsKey a -> AsKey a -> AsKey a
** :: AsKey a -> AsKey a -> AsKey a
$clogBase :: forall a. Floating a => AsKey a -> AsKey a -> AsKey a
logBase :: AsKey a -> AsKey a -> AsKey a
$csin :: forall a. Floating a => AsKey a -> AsKey a
sin :: AsKey a -> AsKey a
$ccos :: forall a. Floating a => AsKey a -> AsKey a
cos :: AsKey a -> AsKey a
$ctan :: forall a. Floating a => AsKey a -> AsKey a
tan :: AsKey a -> AsKey a
$casin :: forall a. Floating a => AsKey a -> AsKey a
asin :: AsKey a -> AsKey a
$cacos :: forall a. Floating a => AsKey a -> AsKey a
acos :: AsKey a -> AsKey a
$catan :: forall a. Floating a => AsKey a -> AsKey a
atan :: AsKey a -> AsKey a
$csinh :: forall a. Floating a => AsKey a -> AsKey a
sinh :: AsKey a -> AsKey a
$ccosh :: forall a. Floating a => AsKey a -> AsKey a
cosh :: AsKey a -> AsKey a
$ctanh :: forall a. Floating a => AsKey a -> AsKey a
tanh :: AsKey a -> AsKey a
$casinh :: forall a. Floating a => AsKey a -> AsKey a
asinh :: AsKey a -> AsKey a
$cacosh :: forall a. Floating a => AsKey a -> AsKey a
acosh :: AsKey a -> AsKey a
$catanh :: forall a. Floating a => AsKey a -> AsKey a
atanh :: AsKey a -> AsKey a
$clog1p :: forall a. Floating a => AsKey a -> AsKey a
log1p :: AsKey a -> AsKey a
$cexpm1 :: forall a. Floating a => AsKey a -> AsKey a
expm1 :: AsKey a -> AsKey a
$clog1pexp :: forall a. Floating a => AsKey a -> AsKey a
log1pexp :: AsKey a -> AsKey a
$clog1mexp :: forall a. Floating a => AsKey a -> AsKey a
log1mexp :: AsKey a -> AsKey a
Floating
    )
  deriving stock ((forall a b. (a -> b) -> AsKey a -> AsKey b)
-> (forall a b. a -> AsKey b -> AsKey a) -> Functor AsKey
forall a b. a -> AsKey b -> AsKey a
forall a b. (a -> b) -> AsKey a -> AsKey b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
$cfmap :: forall a b. (a -> b) -> AsKey a -> AsKey b
fmap :: forall a b. (a -> b) -> AsKey a -> AsKey b
$c<$ :: forall a b. a -> AsKey b -> AsKey a
<$ :: forall a b. a -> AsKey b -> AsKey a
Functor, (forall (m :: * -> *). Quote m => AsKey a -> m Exp)
-> (forall (m :: * -> *). Quote m => AsKey a -> Code m (AsKey a))
-> Lift (AsKey a)
forall a (m :: * -> *). (Lift a, Quote m) => AsKey a -> m Exp
forall a (m :: * -> *).
(Lift a, Quote m) =>
AsKey a -> Code m (AsKey a)
forall t.
(forall (m :: * -> *). Quote m => t -> m Exp)
-> (forall (m :: * -> *). Quote m => t -> Code m t) -> Lift t
forall (m :: * -> *). Quote m => AsKey a -> m Exp
forall (m :: * -> *). Quote m => AsKey a -> Code m (AsKey a)
$clift :: forall a (m :: * -> *). (Lift a, Quote m) => AsKey a -> m Exp
lift :: forall (m :: * -> *). Quote m => AsKey a -> m Exp
$cliftTyped :: forall a (m :: * -> *).
(Lift a, Quote m) =>
AsKey a -> Code m (AsKey a)
liftTyped :: forall (m :: * -> *). Quote m => AsKey a -> Code m (AsKey a)
Lift)

-- | Use a union as a key with identity equality.
--
-- For example, @t'AsKey1' t'Grisette.Core.Union'@ uses the term identity
-- for t'Grisette.Core.Union'.
newtype AsKey1 f a = AsKey1 {forall (f :: * -> *) a. AsKey1 f a -> f a
getAsKey1 :: f a}
  deriving newtype
    ( Get (AsKey1 f a)
[AsKey1 f a] -> Put
AsKey1 f a -> Put
(AsKey1 f a -> Put)
-> Get (AsKey1 f a) -> ([AsKey1 f a] -> Put) -> Binary (AsKey1 f a)
forall t. (t -> Put) -> Get t -> ([t] -> Put) -> Binary t
forall (f :: * -> *) a. Binary (f a) => Get (AsKey1 f a)
forall (f :: * -> *) a. Binary (f a) => [AsKey1 f a] -> Put
forall (f :: * -> *) a. Binary (f a) => AsKey1 f a -> Put
$cput :: forall (f :: * -> *) a. Binary (f a) => AsKey1 f a -> Put
put :: AsKey1 f a -> Put
$cget :: forall (f :: * -> *) a. Binary (f a) => Get (AsKey1 f a)
get :: Get (AsKey1 f a)
$cputList :: forall (f :: * -> *) a. Binary (f a) => [AsKey1 f a] -> Put
putList :: [AsKey1 f a] -> Put
Binary.Binary,
      Get (AsKey1 f a)
Putter (AsKey1 f a)
Putter (AsKey1 f a) -> Get (AsKey1 f a) -> Serialize (AsKey1 f a)
forall t. Putter t -> Get t -> Serialize t
forall (f :: * -> *) a. Serialize (f a) => Get (AsKey1 f a)
forall (f :: * -> *) a. Serialize (f a) => Putter (AsKey1 f a)
$cput :: forall (f :: * -> *) a. Serialize (f a) => Putter (AsKey1 f a)
put :: Putter (AsKey1 f a)
$cget :: forall (f :: * -> *) a. Serialize (f a) => Get (AsKey1 f a)
get :: Get (AsKey1 f a)
Cereal.Serialize,
      String -> AsKey1 f a
(String -> AsKey1 f a) -> IsString (AsKey1 f a)
forall a. (String -> a) -> IsString a
forall (f :: * -> *) a. IsString (f a) => String -> AsKey1 f a
$cfromString :: forall (f :: * -> *) a. IsString (f a) => String -> AsKey1 f a
fromString :: String -> AsKey1 f a
IsString,
      Int -> AsKey1 f a -> ShowS
[AsKey1 f a] -> ShowS
AsKey1 f a -> String
(Int -> AsKey1 f a -> ShowS)
-> (AsKey1 f a -> String)
-> ([AsKey1 f a] -> ShowS)
-> Show (AsKey1 f a)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall (f :: * -> *) a. Show (f a) => Int -> AsKey1 f a -> ShowS
forall (f :: * -> *) a. Show (f a) => [AsKey1 f a] -> ShowS
forall (f :: * -> *) a. Show (f a) => AsKey1 f a -> String
$cshowsPrec :: forall (f :: * -> *) a. Show (f a) => Int -> AsKey1 f a -> ShowS
showsPrec :: Int -> AsKey1 f a -> ShowS
$cshow :: forall (f :: * -> *) a. Show (f a) => AsKey1 f a -> String
show :: AsKey1 f a -> String
$cshowList :: forall (f :: * -> *) a. Show (f a) => [AsKey1 f a] -> ShowS
showList :: [AsKey1 f a] -> ShowS
Show,
      (forall a. Show a => Show (AsKey1 f a)) =>
(forall a.
 (Int -> a -> ShowS)
 -> ([a] -> ShowS) -> Int -> AsKey1 f a -> ShowS)
-> (forall a.
    (Int -> a -> ShowS) -> ([a] -> ShowS) -> [AsKey1 f a] -> ShowS)
-> Show1 (AsKey1 f)
forall a. Show a => Show (AsKey1 f a)
forall a.
(Int -> a -> ShowS) -> ([a] -> ShowS) -> Int -> AsKey1 f a -> ShowS
forall a.
(Int -> a -> ShowS) -> ([a] -> ShowS) -> [AsKey1 f a] -> ShowS
forall (f :: * -> *) a. (Show1 f, Show a) => Show (AsKey1 f a)
forall (f :: * -> *) a.
Show1 f =>
(Int -> a -> ShowS) -> ([a] -> ShowS) -> Int -> AsKey1 f a -> ShowS
forall (f :: * -> *) a.
Show1 f =>
(Int -> a -> ShowS) -> ([a] -> ShowS) -> [AsKey1 f a] -> ShowS
forall (f :: * -> *).
(forall a. Show a => Show (f a)) =>
(forall a.
 (Int -> a -> ShowS) -> ([a] -> ShowS) -> Int -> f a -> ShowS)
-> (forall a.
    (Int -> a -> ShowS) -> ([a] -> ShowS) -> [f a] -> ShowS)
-> Show1 f
$cliftShowsPrec :: forall (f :: * -> *) a.
Show1 f =>
(Int -> a -> ShowS) -> ([a] -> ShowS) -> Int -> AsKey1 f a -> ShowS
liftShowsPrec :: forall a.
(Int -> a -> ShowS) -> ([a] -> ShowS) -> Int -> AsKey1 f a -> ShowS
$cliftShowList :: forall (f :: * -> *) a.
Show1 f =>
(Int -> a -> ShowS) -> ([a] -> ShowS) -> [AsKey1 f a] -> ShowS
liftShowList :: forall a.
(Int -> a -> ShowS) -> ([a] -> ShowS) -> [AsKey1 f a] -> ShowS
Show1,
      (forall a b. (a -> b) -> AsKey1 f a -> AsKey1 f b)
-> (forall a b. a -> AsKey1 f b -> AsKey1 f a)
-> Functor (AsKey1 f)
forall a b. a -> AsKey1 f b -> AsKey1 f a
forall a b. (a -> b) -> AsKey1 f a -> AsKey1 f b
forall (f :: * -> *) a b.
Functor f =>
a -> AsKey1 f b -> AsKey1 f a
forall (f :: * -> *) a b.
Functor f =>
(a -> b) -> AsKey1 f a -> AsKey1 f b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
$cfmap :: forall (f :: * -> *) a b.
Functor f =>
(a -> b) -> AsKey1 f a -> AsKey1 f b
fmap :: forall a b. (a -> b) -> AsKey1 f a -> AsKey1 f b
$c<$ :: forall (f :: * -> *) a b.
Functor f =>
a -> AsKey1 f b -> AsKey1 f a
<$ :: forall a b. a -> AsKey1 f b -> AsKey1 f a
Functor,
      AsKey1 f a -> ()
(AsKey1 f a -> ()) -> NFData (AsKey1 f a)
forall a. (a -> ()) -> NFData a
forall (f :: * -> *) a. NFData (f a) => AsKey1 f a -> ()
$crnf :: forall (f :: * -> *) a. NFData (f a) => AsKey1 f a -> ()
rnf :: AsKey1 f a -> ()
NFData,
      (forall a. NFData a => NFData (AsKey1 f a)) =>
(forall a. (a -> ()) -> AsKey1 f a -> ()) -> NFData1 (AsKey1 f)
forall a. NFData a => NFData (AsKey1 f a)
forall a. (a -> ()) -> AsKey1 f a -> ()
forall (f :: * -> *) a.
(NFData1 f, NFData a) =>
NFData (AsKey1 f a)
forall (f :: * -> *) a. NFData1 f => (a -> ()) -> AsKey1 f a -> ()
forall (f :: * -> *).
(forall a. NFData a => NFData (f a)) =>
(forall a. (a -> ()) -> f a -> ()) -> NFData1 f
$cliftRnf :: forall (f :: * -> *) a. NFData1 f => (a -> ()) -> AsKey1 f a -> ()
liftRnf :: forall a. (a -> ()) -> AsKey1 f a -> ()
NFData1,
      Functor (AsKey1 f)
Functor (AsKey1 f) =>
(forall a. a -> AsKey1 f a)
-> (forall a b. AsKey1 f (a -> b) -> AsKey1 f a -> AsKey1 f b)
-> (forall a b c.
    (a -> b -> c) -> AsKey1 f a -> AsKey1 f b -> AsKey1 f c)
-> (forall a b. AsKey1 f a -> AsKey1 f b -> AsKey1 f b)
-> (forall a b. AsKey1 f a -> AsKey1 f b -> AsKey1 f a)
-> Applicative (AsKey1 f)
forall a. a -> AsKey1 f a
forall a b. AsKey1 f a -> AsKey1 f b -> AsKey1 f a
forall a b. AsKey1 f a -> AsKey1 f b -> AsKey1 f b
forall a b. AsKey1 f (a -> b) -> AsKey1 f a -> AsKey1 f b
forall a b c.
(a -> b -> c) -> AsKey1 f a -> AsKey1 f b -> AsKey1 f c
forall (f :: * -> *).
Functor f =>
(forall a. a -> f a)
-> (forall a b. f (a -> b) -> f a -> f b)
-> (forall a b c. (a -> b -> c) -> f a -> f b -> f c)
-> (forall a b. f a -> f b -> f b)
-> (forall a b. f a -> f b -> f a)
-> Applicative f
forall (f :: * -> *). Applicative f => Functor (AsKey1 f)
forall (f :: * -> *) a. Applicative f => a -> AsKey1 f a
forall (f :: * -> *) a b.
Applicative f =>
AsKey1 f a -> AsKey1 f b -> AsKey1 f a
forall (f :: * -> *) a b.
Applicative f =>
AsKey1 f a -> AsKey1 f b -> AsKey1 f b
forall (f :: * -> *) a b.
Applicative f =>
AsKey1 f (a -> b) -> AsKey1 f a -> AsKey1 f b
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> AsKey1 f a -> AsKey1 f b -> AsKey1 f c
$cpure :: forall (f :: * -> *) a. Applicative f => a -> AsKey1 f a
pure :: forall a. a -> AsKey1 f a
$c<*> :: forall (f :: * -> *) a b.
Applicative f =>
AsKey1 f (a -> b) -> AsKey1 f a -> AsKey1 f b
<*> :: forall a b. AsKey1 f (a -> b) -> AsKey1 f a -> AsKey1 f b
$cliftA2 :: forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> AsKey1 f a -> AsKey1 f b -> AsKey1 f c
liftA2 :: forall a b c.
(a -> b -> c) -> AsKey1 f a -> AsKey1 f b -> AsKey1 f c
$c*> :: forall (f :: * -> *) a b.
Applicative f =>
AsKey1 f a -> AsKey1 f b -> AsKey1 f b
*> :: forall a b. AsKey1 f a -> AsKey1 f b -> AsKey1 f b
$c<* :: forall (f :: * -> *) a b.
Applicative f =>
AsKey1 f a -> AsKey1 f b -> AsKey1 f a
<* :: forall a b. AsKey1 f a -> AsKey1 f b -> AsKey1 f a
Applicative,
      Applicative (AsKey1 f)
Applicative (AsKey1 f) =>
(forall a b. AsKey1 f a -> (a -> AsKey1 f b) -> AsKey1 f b)
-> (forall a b. AsKey1 f a -> AsKey1 f b -> AsKey1 f b)
-> (forall a. a -> AsKey1 f a)
-> Monad (AsKey1 f)
forall a. a -> AsKey1 f a
forall a b. AsKey1 f a -> AsKey1 f b -> AsKey1 f b
forall a b. AsKey1 f a -> (a -> AsKey1 f b) -> AsKey1 f b
forall (f :: * -> *). Monad f => Applicative (AsKey1 f)
forall (f :: * -> *) a. Monad f => a -> AsKey1 f a
forall (f :: * -> *) a b.
Monad f =>
AsKey1 f a -> AsKey1 f b -> AsKey1 f b
forall (f :: * -> *) a b.
Monad f =>
AsKey1 f a -> (a -> AsKey1 f b) -> AsKey1 f b
forall (m :: * -> *).
Applicative m =>
(forall a b. m a -> (a -> m b) -> m b)
-> (forall a b. m a -> m b -> m b)
-> (forall a. a -> m a)
-> Monad m
$c>>= :: forall (f :: * -> *) a b.
Monad f =>
AsKey1 f a -> (a -> AsKey1 f b) -> AsKey1 f b
>>= :: forall a b. AsKey1 f a -> (a -> AsKey1 f b) -> AsKey1 f b
$c>> :: forall (f :: * -> *) a b.
Monad f =>
AsKey1 f a -> AsKey1 f b -> AsKey1 f b
>> :: forall a b. AsKey1 f a -> AsKey1 f b -> AsKey1 f b
$creturn :: forall (f :: * -> *) a. Monad f => a -> AsKey1 f a
return :: forall a. a -> AsKey1 f a
Monad,
      Integer -> AsKey1 f a
AsKey1 f a -> AsKey1 f a
AsKey1 f a -> AsKey1 f a -> AsKey1 f a
(AsKey1 f a -> AsKey1 f a -> AsKey1 f a)
-> (AsKey1 f a -> AsKey1 f a -> AsKey1 f a)
-> (AsKey1 f a -> AsKey1 f a -> AsKey1 f a)
-> (AsKey1 f a -> AsKey1 f a)
-> (AsKey1 f a -> AsKey1 f a)
-> (AsKey1 f a -> AsKey1 f a)
-> (Integer -> AsKey1 f a)
-> Num (AsKey1 f a)
forall a.
(a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (Integer -> a)
-> Num a
forall (f :: * -> *) a. Num (f a) => Integer -> AsKey1 f a
forall (f :: * -> *) a. Num (f a) => AsKey1 f a -> AsKey1 f a
forall (f :: * -> *) a.
Num (f a) =>
AsKey1 f a -> AsKey1 f a -> AsKey1 f a
$c+ :: forall (f :: * -> *) a.
Num (f a) =>
AsKey1 f a -> AsKey1 f a -> AsKey1 f a
+ :: AsKey1 f a -> AsKey1 f a -> AsKey1 f a
$c- :: forall (f :: * -> *) a.
Num (f a) =>
AsKey1 f a -> AsKey1 f a -> AsKey1 f a
- :: AsKey1 f a -> AsKey1 f a -> AsKey1 f a
$c* :: forall (f :: * -> *) a.
Num (f a) =>
AsKey1 f a -> AsKey1 f a -> AsKey1 f a
* :: AsKey1 f a -> AsKey1 f a -> AsKey1 f a
$cnegate :: forall (f :: * -> *) a. Num (f a) => AsKey1 f a -> AsKey1 f a
negate :: AsKey1 f a -> AsKey1 f a
$cabs :: forall (f :: * -> *) a. Num (f a) => AsKey1 f a -> AsKey1 f a
abs :: AsKey1 f a -> AsKey1 f a
$csignum :: forall (f :: * -> *) a. Num (f a) => AsKey1 f a -> AsKey1 f a
signum :: AsKey1 f a -> AsKey1 f a
$cfromInteger :: forall (f :: * -> *) a. Num (f a) => Integer -> AsKey1 f a
fromInteger :: Integer -> AsKey1 f a
Num
    )
  deriving stock ((forall (m :: * -> *). Quote m => AsKey1 f a -> m Exp)
-> (forall (m :: * -> *).
    Quote m =>
    AsKey1 f a -> Code m (AsKey1 f a))
-> Lift (AsKey1 f a)
forall t.
(forall (m :: * -> *). Quote m => t -> m Exp)
-> (forall (m :: * -> *). Quote m => t -> Code m t) -> Lift t
forall (m :: * -> *). Quote m => AsKey1 f a -> m Exp
forall (m :: * -> *). Quote m => AsKey1 f a -> Code m (AsKey1 f a)
forall (f :: * -> *) a (m :: * -> *).
(Lift (f a), Quote m) =>
AsKey1 f a -> m Exp
forall (f :: * -> *) a (m :: * -> *).
(Lift (f a), Quote m) =>
AsKey1 f a -> Code m (AsKey1 f a)
$clift :: forall (f :: * -> *) a (m :: * -> *).
(Lift (f a), Quote m) =>
AsKey1 f a -> m Exp
lift :: forall (m :: * -> *). Quote m => AsKey1 f a -> m Exp
$cliftTyped :: forall (f :: * -> *) a (m :: * -> *).
(Lift (f a), Quote m) =>
AsKey1 f a -> Code m (AsKey1 f a)
liftTyped :: forall (m :: * -> *). Quote m => AsKey1 f a -> Code m (AsKey1 f a)
Lift)

instance (Serial.Serial a) => Serial.Serial (AsKey a) where
  serialize :: forall (m :: * -> *). MonadPut m => AsKey a -> m ()
serialize = a -> m ()
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
forall (m :: * -> *). MonadPut m => a -> m ()
Serial.serialize (a -> m ()) -> (AsKey a -> a) -> AsKey a -> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. AsKey a -> a
forall a. AsKey a -> a
getAsKey
  deserialize :: forall (m :: * -> *). MonadGet m => m (AsKey a)
deserialize = a -> AsKey a
forall a. a -> AsKey a
AsKey (a -> AsKey a) -> m a -> m (AsKey a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m a
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
forall (m :: * -> *). MonadGet m => m a
Serial.deserialize

instance (Serial.Serial a, Serial.Serial1 f) => Serial.Serial (AsKey1 f a) where
  serialize :: forall (m :: * -> *). MonadPut m => AsKey1 f a -> m ()
serialize = f a -> m ()
forall (m :: * -> *) (f :: * -> *) a.
(MonadPut m, Serial1 f, Serial a) =>
f a -> m ()
Serial.serialize1 (f a -> m ()) -> (AsKey1 f a -> f a) -> AsKey1 f a -> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. AsKey1 f a -> f a
forall (f :: * -> *) a. AsKey1 f a -> f a
getAsKey1
  deserialize :: forall (m :: * -> *). MonadGet m => m (AsKey1 f a)
deserialize = f a -> AsKey1 f a
forall (f :: * -> *) a. f a -> AsKey1 f a
AsKey1 (f a -> AsKey1 f a) -> m (f a) -> m (AsKey1 f a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m (f a)
forall (m :: * -> *) (f :: * -> *) a.
(MonadGet m, Serial1 f, Serial a) =>
m (f a)
Serial.deserialize1

instance (KeyEq a) => Eq (AsKey a) where
  (AsKey a
a) == :: AsKey a -> AsKey a -> Bool
== (AsKey a
b) = a -> a -> Bool
forall a. KeyEq a => a -> a -> Bool
keyEq a
a a
b

instance (KeyEq1 f, Eq a) => Eq (AsKey1 f a) where
  == :: AsKey1 f a -> AsKey1 f a -> Bool
(==) = AsKey1 f a -> AsKey1 f a -> Bool
forall (f :: * -> *) a. (Eq1 f, Eq a) => f a -> f a -> Bool
eq1

instance (KeyEq1 f) => Eq1 (AsKey1 f) where
  liftEq :: forall a b. (a -> b -> Bool) -> AsKey1 f a -> AsKey1 f b -> Bool
liftEq a -> b -> Bool
f (AsKey1 f a
a) (AsKey1 f b
b) = (a -> b -> Bool) -> f a -> f b -> Bool
forall a b. (a -> b -> Bool) -> f a -> f b -> Bool
forall (f :: * -> *) a b.
KeyEq1 f =>
(a -> b -> Bool) -> f a -> f b -> Bool
liftKeyEq a -> b -> Bool
f f a
a f b
b

instance (KeyOrd a) => Ord (AsKey a) where
  compare :: AsKey a -> AsKey a -> Ordering
compare (AsKey a
a) (AsKey a
b) = a -> a -> Ordering
forall a. KeyOrd a => a -> a -> Ordering
keyCompare a
a a
b

instance (KeyHashable a) => Hashable (AsKey a) where
  hashWithSalt :: Int -> AsKey a -> Int
hashWithSalt Int
salt = Int -> a -> Int
forall a. KeyHashable a => Int -> a -> Int
keyHashWithSalt Int
salt (a -> Int) -> (AsKey a -> a) -> AsKey a -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. AsKey a -> a
forall a. AsKey a -> a
getAsKey

instance (KeyOrd1 f, Ord a) => Ord (AsKey1 f a) where
  compare :: AsKey1 f a -> AsKey1 f a -> Ordering
compare = AsKey1 f a -> AsKey1 f a -> Ordering
forall (f :: * -> *) a. (Ord1 f, Ord a) => f a -> f a -> Ordering
compare1

instance (KeyOrd1 f) => Ord1 (AsKey1 f) where
  liftCompare :: forall a b.
(a -> b -> Ordering) -> AsKey1 f a -> AsKey1 f b -> Ordering
liftCompare a -> b -> Ordering
f (AsKey1 f a
a) (AsKey1 f b
b) = (a -> b -> Ordering) -> f a -> f b -> Ordering
forall a b. (a -> b -> Ordering) -> f a -> f b -> Ordering
forall (f :: * -> *) a b.
KeyOrd1 f =>
(a -> b -> Ordering) -> f a -> f b -> Ordering
liftKeyCompare a -> b -> Ordering
f f a
a f b
b

instance (KeyHashable1 f, Hashable a) => Hashable (AsKey1 f a) where
  hashWithSalt :: Int -> AsKey1 f a -> Int
hashWithSalt = Int -> AsKey1 f a -> Int
forall (f :: * -> *) a.
(Hashable1 f, Hashable a) =>
Int -> f a -> Int
hashWithSalt1

instance (KeyHashable1 f) => Hashable1 (AsKey1 f) where
  liftHashWithSalt :: forall a. (Int -> a -> Int) -> Int -> AsKey1 f a -> Int
liftHashWithSalt Int -> a -> Int
f Int
salt (AsKey1 f a
a) = (Int -> a -> Int) -> Int -> f a -> Int
forall a. (Int -> a -> Int) -> Int -> f a -> Int
forall (f :: * -> *) a.
KeyHashable1 f =>
(Int -> a -> Int) -> Int -> f a -> Int
liftKeyHashWithSalt Int -> a -> Int
f Int
salt f a
a

shouldUseAsKeyError :: (HasCallStack) => String -> String -> a
shouldUseAsKeyError :: forall a. HasCallStack => String -> String -> a
shouldUseAsKeyError String
typ String
op =
  String -> a
forall a. HasCallStack => String -> a
error (String -> a) -> String -> a
forall a b. (a -> b) -> a -> b
$
    String
"As "
      String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
typ
      String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
" is a symbolic type, "
      String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
op
      String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
" is likely not going to work as expected.\n"
      String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
"You should use AsKey if you do want term identity based "
      String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
op
      String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
" on "
      String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
typ
      String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
"."

shouldUseAsKeyHasSymbolicVersionError ::
  (HasCallStack) => String -> String -> String -> a
shouldUseAsKeyHasSymbolicVersionError :: forall a. HasCallStack => String -> String -> String -> a
shouldUseAsKeyHasSymbolicVersionError String
typ String
op String
symop =
  String -> a
forall a. HasCallStack => String -> a
error (String -> a) -> String -> a
forall a b. (a -> b) -> a -> b
$
    String
"As "
      String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
typ
      String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
" is a symbolic type, "
      String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
op
      String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
" is likely not going to work as expected.\n"
      String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
"You should use AsKey if you do want term identity based "
      String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
op
      String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
" on "
      String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
typ
      String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
",\n or use "
      String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
symop
      String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
" instead if you want symbolic version of "
      String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
op
      String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
"."

shouldUseSymbolicVersionError ::
  (HasCallStack) => String -> String -> String -> a
shouldUseSymbolicVersionError :: forall a. HasCallStack => String -> String -> String -> a
shouldUseSymbolicVersionError String
typ String
op String
symop =
  String -> a
forall a. HasCallStack => String -> a
error (String -> a) -> String -> a
forall a b. (a -> b) -> a -> b
$
    String
"As "
      String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
typ
      String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
" is a symbolic type, "
      String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
op
      String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
" is likely not going to work as expected.\n"
      String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
"You should use "
      String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
symop
      String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
" instead if you want symbolic version of "
      String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
op
      String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
"."

instance (Function a arg res) => Function (AsKey a) arg res where
  (AsKey a
a) # :: AsKey a -> arg -> res
# arg
b = a
a a -> arg -> res
forall f arg ret. Function f arg ret => f -> arg -> ret
# arg
b

instance
  (Function (f a) arg (f res)) =>
  Function (AsKey1 f a) arg (AsKey1 f res)
  where
  (AsKey1 f a
f) # :: AsKey1 f a -> arg -> AsKey1 f res
# arg
b = f res -> AsKey1 f res
forall (f :: * -> *) a. f a -> AsKey1 f a
AsKey1 (f res -> AsKey1 f res) -> f res -> AsKey1 f res
forall a b. (a -> b) -> a -> b
$ f a
f f a -> arg -> f res
forall f arg ret. Function f arg ret => f -> arg -> ret
# arg
b

instance (Apply a) => Apply (AsKey a) where
  type FunType (AsKey a) = FunType a
  apply :: AsKey a -> FunType (AsKey a)
apply (AsKey a
a) = a -> FunType a
forall uf. Apply uf => uf -> FunType uf
apply a
a

instance (ConRep a) => ConRep (AsKey a) where
  type ConType (AsKey a) = ConType a

instance {-# INCOHERENT #-} (BitCast a b) => BitCast (AsKey a) (AsKey b) where
  bitCast :: AsKey a -> AsKey b
bitCast (AsKey a
a) = b -> AsKey b
forall a. a -> AsKey a
AsKey (b -> AsKey b) -> b -> AsKey b
forall a b. (a -> b) -> a -> b
$ a -> b
forall from to. BitCast from to => from -> to
bitCast a
a
  {-# INLINE bitCast #-}

instance {-# INCOHERENT #-} (BitCast a b) => BitCast a (AsKey b) where
  bitCast :: a -> AsKey b
bitCast a
a = b -> AsKey b
forall a. a -> AsKey a
AsKey (b -> AsKey b) -> b -> AsKey b
forall a b. (a -> b) -> a -> b
$ a -> b
forall from to. BitCast from to => from -> to
bitCast a
a
  {-# INLINE bitCast #-}

instance {-# INCOHERENT #-} (BitCast a b) => BitCast (AsKey a) b where
  bitCast :: AsKey a -> b
bitCast (AsKey a
a) = a -> b
forall from to. BitCast from to => from -> to
bitCast a
a
  {-# INLINE bitCast #-}

instance
  {-# INCOHERENT #-}
  (BitCastCanonical a b) =>
  BitCastCanonical (AsKey a) (AsKey b)
  where
  bitCastCanonicalValue :: forall (proxy :: * -> *). proxy (AsKey a) -> AsKey b
bitCastCanonicalValue proxy (AsKey a)
_ = b -> AsKey b
forall a. a -> AsKey a
AsKey (b -> AsKey b) -> b -> AsKey b
forall a b. (a -> b) -> a -> b
$ Proxy a -> b
forall from to (proxy :: * -> *).
BitCastCanonical from to =>
proxy from -> to
forall (proxy :: * -> *). proxy a -> b
bitCastCanonicalValue (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @a)

instance
  {-# INCOHERENT #-}
  (BitCastCanonical a b) =>
  BitCastCanonical (AsKey a) b
  where
  bitCastCanonicalValue :: forall (proxy :: * -> *). proxy (AsKey a) -> b
bitCastCanonicalValue proxy (AsKey a)
_ = Proxy a -> b
forall from to (proxy :: * -> *).
BitCastCanonical from to =>
proxy from -> to
forall (proxy :: * -> *). proxy a -> b
bitCastCanonicalValue (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @a)

instance
  {-# INCOHERENT #-}
  (BitCastCanonical a b) =>
  BitCastCanonical a (AsKey b)
  where
  bitCastCanonicalValue :: forall (proxy :: * -> *). proxy a -> AsKey b
bitCastCanonicalValue proxy a
p = b -> AsKey b
forall a. a -> AsKey a
AsKey (b -> AsKey b) -> b -> AsKey b
forall a b. (a -> b) -> a -> b
$ proxy a -> b
forall from to (proxy :: * -> *).
BitCastCanonical from to =>
proxy from -> to
forall (proxy :: * -> *). proxy a -> b
bitCastCanonicalValue proxy a
p

instance (SignConversion a b) => SignConversion (AsKey a) (AsKey b) where
  toSigned :: AsKey a -> AsKey b
toSigned (AsKey a
a) = b -> AsKey b
forall a. a -> AsKey a
AsKey (b -> AsKey b) -> b -> AsKey b
forall a b. (a -> b) -> a -> b
$ a -> b
forall ubv sbv. SignConversion ubv sbv => ubv -> sbv
toSigned a
a
  toUnsigned :: AsKey b -> AsKey a
toUnsigned (AsKey b
a) = a -> AsKey a
forall a. a -> AsKey a
AsKey (a -> AsKey a) -> a -> AsKey a
forall a b. (a -> b) -> a -> b
$ b -> a
forall ubv sbv. SignConversion ubv sbv => sbv -> ubv
toUnsigned b
a

instance (IEEEFPConstants a) => IEEEFPConstants (AsKey a) where
  fpPositiveInfinite :: AsKey a
fpPositiveInfinite = a -> AsKey a
forall a. a -> AsKey a
AsKey a
forall a. IEEEFPConstants a => a
fpPositiveInfinite
  fpNegativeInfinite :: AsKey a
fpNegativeInfinite = a -> AsKey a
forall a. a -> AsKey a
AsKey a
forall a. IEEEFPConstants a => a
fpNegativeInfinite
  fpNaN :: AsKey a
fpNaN = a -> AsKey a
forall a. a -> AsKey a
AsKey a
forall a. IEEEFPConstants a => a
fpNaN
  fpNegativeZero :: AsKey a
fpNegativeZero = a -> AsKey a
forall a. a -> AsKey a
AsKey a
forall a. IEEEFPConstants a => a
fpNegativeZero
  fpPositiveZero :: AsKey a
fpPositiveZero = a -> AsKey a
forall a. a -> AsKey a
AsKey a
forall a. IEEEFPConstants a => a
fpPositiveZero
  fpMinNormalized :: AsKey a
fpMinNormalized = a -> AsKey a
forall a. a -> AsKey a
AsKey a
forall a. IEEEFPConstants a => a
fpMinNormalized
  fpMinSubnormal :: AsKey a
fpMinSubnormal = a -> AsKey a
forall a. a -> AsKey a
AsKey a
forall a. IEEEFPConstants a => a
fpMinSubnormal
  fpMaxNormalized :: AsKey a
fpMaxNormalized = a -> AsKey a
forall a. a -> AsKey a
AsKey a
forall a. IEEEFPConstants a => a
fpMaxNormalized
  fpMaxSubnormal :: AsKey a
fpMaxSubnormal = a -> AsKey a
forall a. a -> AsKey a
AsKey a
forall a. IEEEFPConstants a => a
fpMaxSubnormal

instance (IEEEFPOp a) => IEEEFPOp (AsKey a) where
  fpAbs :: AsKey a -> AsKey a
fpAbs (AsKey a
a) = a -> AsKey a
forall a. a -> AsKey a
AsKey (a -> AsKey a) -> a -> AsKey a
forall a b. (a -> b) -> a -> b
$ a -> a
forall a. IEEEFPOp a => a -> a
fpAbs a
a
  fpNeg :: AsKey a -> AsKey a
fpNeg (AsKey a
a) = a -> AsKey a
forall a. a -> AsKey a
AsKey (a -> AsKey a) -> a -> AsKey a
forall a b. (a -> b) -> a -> b
$ a -> a
forall a. IEEEFPOp a => a -> a
fpNeg a
a
  fpRem :: AsKey a -> AsKey a -> AsKey a
fpRem (AsKey a
a) (AsKey a
b) = a -> AsKey a
forall a. a -> AsKey a
AsKey (a -> AsKey a) -> a -> AsKey a
forall a b. (a -> b) -> a -> b
$ a -> a -> a
forall a. IEEEFPOp a => a -> a -> a
fpRem a
a a
b
  fpMinimum :: AsKey a -> AsKey a -> AsKey a
fpMinimum (AsKey a
a) (AsKey a
b) = a -> AsKey a
forall a. a -> AsKey a
AsKey (a -> AsKey a) -> a -> AsKey a
forall a b. (a -> b) -> a -> b
$ a -> a -> a
forall a. IEEEFPOp a => a -> a -> a
fpMinimum a
a a
b
  fpMaximum :: AsKey a -> AsKey a -> AsKey a
fpMaximum (AsKey a
a) (AsKey a
b) = a -> AsKey a
forall a. a -> AsKey a
AsKey (a -> AsKey a) -> a -> AsKey a
forall a b. (a -> b) -> a -> b
$ a -> a -> a
forall a. IEEEFPOp a => a -> a -> a
fpMaximum a
a a
b
  fpMinimumNumber :: AsKey a -> AsKey a -> AsKey a
fpMinimumNumber (AsKey a
a) (AsKey a
b) = a -> AsKey a
forall a. a -> AsKey a
AsKey (a -> AsKey a) -> a -> AsKey a
forall a b. (a -> b) -> a -> b
$ a -> a -> a
forall a. IEEEFPOp a => a -> a -> a
fpMinimumNumber a
a a
b
  fpMaximumNumber :: AsKey a -> AsKey a -> AsKey a
fpMaximumNumber (AsKey a
a) (AsKey a
b) = a -> AsKey a
forall a. a -> AsKey a
AsKey (a -> AsKey a) -> a -> AsKey a
forall a b. (a -> b) -> a -> b
$ a -> a -> a
forall a. IEEEFPOp a => a -> a -> a
fpMaximumNumber a
a a
b

instance (IEEEFPRoundingMode a) => IEEEFPRoundingMode (AsKey a) where
  rne :: AsKey a
rne = a -> AsKey a
forall a. a -> AsKey a
AsKey a
forall mode. IEEEFPRoundingMode mode => mode
rne
  rna :: AsKey a
rna = a -> AsKey a
forall a. a -> AsKey a
AsKey a
forall mode. IEEEFPRoundingMode mode => mode
rna
  rtp :: AsKey a
rtp = a -> AsKey a
forall a. a -> AsKey a
AsKey a
forall mode. IEEEFPRoundingMode mode => mode
rtp
  rtn :: AsKey a
rtn = a -> AsKey a
forall a. a -> AsKey a
AsKey a
forall mode. IEEEFPRoundingMode mode => mode
rtn
  rtz :: AsKey a
rtz = a -> AsKey a
forall a. a -> AsKey a
AsKey a
forall mode. IEEEFPRoundingMode mode => mode
rtz

instance
  (IEEEFPRoundingOp a mode) =>
  IEEEFPRoundingOp (AsKey a) (AsKey mode)
  where
  fpAdd :: AsKey mode -> AsKey a -> AsKey a -> AsKey a
fpAdd (AsKey mode
mode) (AsKey a
a) (AsKey a
b) = a -> AsKey a
forall a. a -> AsKey a
AsKey (a -> AsKey a) -> a -> AsKey a
forall a b. (a -> b) -> a -> b
$ mode -> a -> a -> a
forall a mode. IEEEFPRoundingOp a mode => mode -> a -> a -> a
fpAdd mode
mode a
a a
b
  fpSub :: AsKey mode -> AsKey a -> AsKey a -> AsKey a
fpSub (AsKey mode
mode) (AsKey a
a) (AsKey a
b) = a -> AsKey a
forall a. a -> AsKey a
AsKey (a -> AsKey a) -> a -> AsKey a
forall a b. (a -> b) -> a -> b
$ mode -> a -> a -> a
forall a mode. IEEEFPRoundingOp a mode => mode -> a -> a -> a
fpSub mode
mode a
a a
b
  fpMul :: AsKey mode -> AsKey a -> AsKey a -> AsKey a
fpMul (AsKey mode
mode) (AsKey a
a) (AsKey a
b) = a -> AsKey a
forall a. a -> AsKey a
AsKey (a -> AsKey a) -> a -> AsKey a
forall a b. (a -> b) -> a -> b
$ mode -> a -> a -> a
forall a mode. IEEEFPRoundingOp a mode => mode -> a -> a -> a
fpMul mode
mode a
a a
b
  fpDiv :: AsKey mode -> AsKey a -> AsKey a -> AsKey a
fpDiv (AsKey mode
mode) (AsKey a
a) (AsKey a
b) = a -> AsKey a
forall a. a -> AsKey a
AsKey (a -> AsKey a) -> a -> AsKey a
forall a b. (a -> b) -> a -> b
$ mode -> a -> a -> a
forall a mode. IEEEFPRoundingOp a mode => mode -> a -> a -> a
fpDiv mode
mode a
a a
b
  fpFMA :: AsKey mode -> AsKey a -> AsKey a -> AsKey a -> AsKey a
fpFMA (AsKey mode
mode) (AsKey a
a) (AsKey a
b) (AsKey a
c) = a -> AsKey a
forall a. a -> AsKey a
AsKey (a -> AsKey a) -> a -> AsKey a
forall a b. (a -> b) -> a -> b
$ mode -> a -> a -> a -> a
forall a mode. IEEEFPRoundingOp a mode => mode -> a -> a -> a -> a
fpFMA mode
mode a
a a
b a
c
  fpSqrt :: AsKey mode -> AsKey a -> AsKey a
fpSqrt (AsKey mode
mode) (AsKey a
a) = a -> AsKey a
forall a. a -> AsKey a
AsKey (a -> AsKey a) -> a -> AsKey a
forall a b. (a -> b) -> a -> b
$ mode -> a -> a
forall a mode. IEEEFPRoundingOp a mode => mode -> a -> a
fpSqrt mode
mode a
a
  fpRoundToIntegral :: AsKey mode -> AsKey a -> AsKey a
fpRoundToIntegral (AsKey mode
mode) (AsKey a
a) = a -> AsKey a
forall a. a -> AsKey a
AsKey (a -> AsKey a) -> a -> AsKey a
forall a b. (a -> b) -> a -> b
$ mode -> a -> a
forall a mode. IEEEFPRoundingOp a mode => mode -> a -> a
fpRoundToIntegral mode
mode a
a

instance
  {-# INCOHERENT #-}
  (IEEEFPConvertible a fp mode) =>
  IEEEFPConvertible (AsKey a) (AsKey fp) (AsKey mode)
  where
  fromFPOr :: AsKey a -> AsKey mode -> AsKey fp -> AsKey a
fromFPOr (AsKey a
d) (AsKey mode
mode) (AsKey fp
fp) = a -> AsKey a
forall a. a -> AsKey a
AsKey (a -> AsKey a) -> a -> AsKey a
forall a b. (a -> b) -> a -> b
$ a -> mode -> fp -> a
forall a fp mode.
IEEEFPConvertible a fp mode =>
a -> mode -> fp -> a
fromFPOr a
d mode
mode fp
fp
  toFP :: AsKey mode -> AsKey a -> AsKey fp
toFP (AsKey mode
mode) (AsKey a
a) = fp -> AsKey fp
forall a. a -> AsKey a
AsKey (fp -> AsKey fp) -> fp -> AsKey fp
forall a b. (a -> b) -> a -> b
$ mode -> a -> fp
forall a fp mode. IEEEFPConvertible a fp mode => mode -> a -> fp
toFP mode
mode a
a

instance
  {-# INCOHERENT #-}
  (IEEEFPConvertible a fp mode) =>
  IEEEFPConvertible a (AsKey fp) (AsKey mode)
  where
  fromFPOr :: a -> AsKey mode -> AsKey fp -> a
fromFPOr a
a (AsKey mode
mode) (AsKey fp
fp) = a -> mode -> fp -> a
forall a fp mode.
IEEEFPConvertible a fp mode =>
a -> mode -> fp -> a
fromFPOr a
a mode
mode fp
fp
  toFP :: AsKey mode -> a -> AsKey fp
toFP (AsKey mode
mode) a
a = fp -> AsKey fp
forall a. a -> AsKey a
AsKey (fp -> AsKey fp) -> fp -> AsKey fp
forall a b. (a -> b) -> a -> b
$ mode -> a -> fp
forall a fp mode. IEEEFPConvertible a fp mode => mode -> a -> fp
toFP mode
mode a
a

instance
  {-# INCOHERENT #-}
  (IEEEFPConvertible a fp mode) =>
  IEEEFPConvertible (AsKey a) fp mode
  where
  fromFPOr :: AsKey a -> mode -> fp -> AsKey a
fromFPOr (AsKey a
a) mode
mode fp
fp = a -> AsKey a
forall a. a -> AsKey a
AsKey (a -> AsKey a) -> a -> AsKey a
forall a b. (a -> b) -> a -> b
$ a -> mode -> fp -> a
forall a fp mode.
IEEEFPConvertible a fp mode =>
a -> mode -> fp -> a
fromFPOr a
a mode
mode fp
fp
  toFP :: mode -> AsKey a -> fp
toFP mode
mode (AsKey a
a) = mode -> a -> fp
forall a fp mode. IEEEFPConvertible a fp mode => mode -> a -> fp
toFP mode
mode a
a

instance
  {-# INCOHERENT #-}
  (IEEEFPToAlgReal a fp mode) =>
  IEEEFPToAlgReal (AsKey a) (AsKey fp) (AsKey mode)
  where
  fpToAlgReal :: AsKey a -> AsKey fp -> AsKey a
fpToAlgReal (AsKey a
d) (AsKey fp
fp) = a -> AsKey a
forall a. a -> AsKey a
AsKey (a -> AsKey a) -> a -> AsKey a
forall a b. (a -> b) -> a -> b
$ a -> fp -> a
forall a fp mode. IEEEFPToAlgReal a fp mode => a -> fp -> a
fpToAlgReal a
d fp
fp

instance
  {-# INCOHERENT #-}
  (IEEEFPToAlgReal a fp mode) =>
  IEEEFPToAlgReal a (AsKey fp) (AsKey mode)
  where
  fpToAlgReal :: a -> AsKey fp -> a
fpToAlgReal a
a (AsKey fp
fp) = a -> fp -> a
forall a fp mode. IEEEFPToAlgReal a fp mode => a -> fp -> a
fpToAlgReal a
a fp
fp

instance
  {-# INCOHERENT #-}
  (IEEEFPToAlgReal a fp mode) =>
  IEEEFPToAlgReal (AsKey a) fp mode
  where
  fpToAlgReal :: AsKey a -> fp -> AsKey a
fpToAlgReal (AsKey a
d) fp
fp = a -> AsKey a
forall a. a -> AsKey a
AsKey (a -> AsKey a) -> a -> AsKey a
forall a b. (a -> b) -> a -> b
$ a -> fp -> a
forall a fp mode. IEEEFPToAlgReal a fp mode => a -> fp -> a
fpToAlgReal a
d fp
fp

instance Concrete (AsKey a)

instance (BV a) => BV (AsKey a) where
  bvConcat :: AsKey a -> AsKey a -> AsKey a
bvConcat (AsKey a
a) (AsKey a
b) = a -> AsKey a
forall a. a -> AsKey a
AsKey (a -> AsKey a) -> a -> AsKey a
forall a b. (a -> b) -> a -> b
$ a -> a -> a
forall bv. BV bv => bv -> bv -> bv
bvConcat a
a a
b
  bvZext :: Int -> AsKey a -> AsKey a
bvZext Int
n (AsKey a
a) = a -> AsKey a
forall a. a -> AsKey a
AsKey (a -> AsKey a) -> a -> AsKey a
forall a b. (a -> b) -> a -> b
$ Int -> a -> a
forall bv. BV bv => Int -> bv -> bv
bvZext Int
n a
a
  bvSext :: Int -> AsKey a -> AsKey a
bvSext Int
n (AsKey a
a) = a -> AsKey a
forall a. a -> AsKey a
AsKey (a -> AsKey a) -> a -> AsKey a
forall a b. (a -> b) -> a -> b
$ Int -> a -> a
forall bv. BV bv => Int -> bv -> bv
bvSext Int
n a
a
  bvExt :: Int -> AsKey a -> AsKey a
bvExt Int
n (AsKey a
a) = a -> AsKey a
forall a. a -> AsKey a
AsKey (a -> AsKey a) -> a -> AsKey a
forall a b. (a -> b) -> a -> b
$ Int -> a -> a
forall bv. BV bv => Int -> bv -> bv
bvExt Int
n a
a
  bvSelect :: Int -> Int -> AsKey a -> AsKey a
bvSelect Int
ix Int
w (AsKey a
a) = a -> AsKey a
forall a. a -> AsKey a
AsKey (a -> AsKey a) -> a -> AsKey a
forall a b. (a -> b) -> a -> b
$ Int -> Int -> a -> a
forall bv. BV bv => Int -> Int -> bv -> bv
bvSelect Int
ix Int
w a
a
  bv :: forall a. Integral a => Int -> a -> AsKey a
bv Int
n a
a = a -> AsKey a
forall a. a -> AsKey a
AsKey (a -> AsKey a) -> a -> AsKey a
forall a b. (a -> b) -> a -> b
$ Int -> a -> a
forall a. Integral a => Int -> a -> a
forall bv a. (BV bv, Integral a) => Int -> a -> bv
bv Int
n a
a