{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE UndecidableInstances #-}

{-# OPTIONS_GHC -Wno-orphans #-}

-- | Interpretation of tagless expressions

module Dino.Interpretation where

import Dino.Prelude
import qualified Prelude

import Control.Exception (Exception, throw)
import Control.Monad (foldM, unless)
import Control.Monad.Catch (MonadThrow (..))
import Control.Monad.Except (MonadError (..))
import Control.Monad.Identity (Identity (..))
import Control.Monad.Loops (dropWhileM)
import Control.Monad.Reader (MonadReader (..), ReaderT (..))
import Control.Monad.Trans.Except (ExceptT)
import Control.Monad.Writer (WriterT)
import Data.Coerce (coerce)
import Data.HashMap.Strict (HashMap)
import qualified Data.HashMap.Strict as HashMap
import qualified Data.Text as Text
import Data.Proxy (Proxy (..))
import Data.Ratio (denominator, numerator)
import GHC.TypeLits (symbolVal)

import Dino.AST
import Dino.Types
import Dino.Expression



-- Some terminology used in this module:
--
-- We'll refer to the various `...Exp` classes as "syntax classes". (To be
-- exact, the class definitions provide syntax, while the instances provide
-- semantics.)
--
-- "First-order syntax" (FOS) refers to classes that only contain first-order
-- constructs (i.e. no negative occurrences of the `e` type).
--
-- "Higher-order syntax" (HOS) refers to classes that contain higher-order
-- constructs.
--
-- The "intensional" counterpart of a HOS class is a FOS class that uses
-- explicit named variables instead. Intensional classes are only used
-- internally to enable certain interpretations. They should not be exported to
-- the user.



--------------------------------------------------------------------------------
-- * Type checking
--------------------------------------------------------------------------------

-- The `DinoTypeRep` interpretation serves as a proof that Dino expressions can
-- only calculate with "supported types". Or, pragmatically, it means that we
-- can make arbitrary type information available to any sub-expression via
-- `DinoTypeRep`.

instance ConstExp DinoTypeRep where
  lit :: a -> DinoTypeRep a
lit a
_ = DinoTypeRep a
forall a. DinoType a => DinoTypeRep a
dinoTypeRep

instance NumExp DinoTypeRep where
  add :: DinoTypeRep a -> DinoTypeRep a -> DinoTypeRep a
add DinoTypeRep a
t DinoTypeRep a
_         = DinoTypeRep a
t
  sub :: DinoTypeRep a -> DinoTypeRep a -> DinoTypeRep a
sub DinoTypeRep a
t DinoTypeRep a
_         = DinoTypeRep a
t
  mul :: DinoTypeRep a -> DinoTypeRep a -> DinoTypeRep a
mul DinoTypeRep a
t DinoTypeRep a
_         = DinoTypeRep a
t
  absE :: DinoTypeRep a -> DinoTypeRep a
absE DinoTypeRep a
t          = DinoTypeRep a
t
  signE :: DinoTypeRep a -> DinoTypeRep a
signE DinoTypeRep a
t         = DinoTypeRep a
t
  fromIntegral :: DinoTypeRep a -> DinoTypeRep b
fromIntegral DinoTypeRep a
_  = DinoTypeRep b
forall a. DinoType a => DinoTypeRep a
dinoTypeRep
  floor :: DinoTypeRep a -> DinoTypeRep b
floor DinoTypeRep a
_         = DinoTypeRep b
forall a. DinoType a => DinoTypeRep a
dinoTypeRep
  truncate :: DinoTypeRep a -> DinoTypeRep b
truncate DinoTypeRep a
_      = DinoTypeRep b
forall a. DinoType a => DinoTypeRep a
dinoTypeRep
  roundN :: Int -> DinoTypeRep a -> DinoTypeRep a
roundN Int
_ DinoTypeRep a
t      = DinoTypeRep a
t

instance FracExp DinoTypeRep where
  fdiv :: DinoTypeRep a -> DinoTypeRep a -> DinoTypeRep a
fdiv DinoTypeRep a
t DinoTypeRep a
_ = DinoTypeRep a
t

instance LogicExp DinoTypeRep where
  not :: DinoTypeRep Bool -> DinoTypeRep Bool
not DinoTypeRep Bool
_    = DinoTypeRep Bool
forall a. DinoType a => DinoTypeRep a
dinoTypeRep
  conj :: DinoTypeRep Bool -> DinoTypeRep Bool -> DinoTypeRep Bool
conj DinoTypeRep Bool
_ DinoTypeRep Bool
_ = DinoTypeRep Bool
forall a. DinoType a => DinoTypeRep a
dinoTypeRep
  disj :: DinoTypeRep Bool -> DinoTypeRep Bool -> DinoTypeRep Bool
disj DinoTypeRep Bool
_ DinoTypeRep Bool
_ = DinoTypeRep Bool
forall a. DinoType a => DinoTypeRep a
dinoTypeRep
  xor :: DinoTypeRep Bool -> DinoTypeRep Bool -> DinoTypeRep Bool
xor DinoTypeRep Bool
_ DinoTypeRep Bool
_  = DinoTypeRep Bool
forall a. DinoType a => DinoTypeRep a
dinoTypeRep

instance CompareExp DinoTypeRep where
  eq :: DinoTypeRep a -> DinoTypeRep a -> DinoTypeRep Bool
eq  DinoTypeRep a
_ DinoTypeRep a
_ = DinoTypeRep Bool
forall a. DinoType a => DinoTypeRep a
dinoTypeRep
  neq :: DinoTypeRep a -> DinoTypeRep a -> DinoTypeRep Bool
neq DinoTypeRep a
_ DinoTypeRep a
_ = DinoTypeRep Bool
forall a. DinoType a => DinoTypeRep a
dinoTypeRep
  lt :: DinoTypeRep a -> DinoTypeRep a -> DinoTypeRep Bool
lt  DinoTypeRep a
_ DinoTypeRep a
_ = DinoTypeRep Bool
forall a. DinoType a => DinoTypeRep a
dinoTypeRep
  gt :: DinoTypeRep a -> DinoTypeRep a -> DinoTypeRep Bool
gt  DinoTypeRep a
_ DinoTypeRep a
_ = DinoTypeRep Bool
forall a. DinoType a => DinoTypeRep a
dinoTypeRep
  lte :: DinoTypeRep a -> DinoTypeRep a -> DinoTypeRep Bool
lte DinoTypeRep a
_ DinoTypeRep a
_ = DinoTypeRep Bool
forall a. DinoType a => DinoTypeRep a
dinoTypeRep
  gte :: DinoTypeRep a -> DinoTypeRep a -> DinoTypeRep Bool
gte DinoTypeRep a
_ DinoTypeRep a
_ = DinoTypeRep Bool
forall a. DinoType a => DinoTypeRep a
dinoTypeRep
  min :: DinoTypeRep a -> DinoTypeRep a -> DinoTypeRep a
min DinoTypeRep a
t DinoTypeRep a
_ = DinoTypeRep a
t
  max :: DinoTypeRep a -> DinoTypeRep a -> DinoTypeRep a
max DinoTypeRep a
t DinoTypeRep a
_ = DinoTypeRep a
t

instance CondExpFO DinoTypeRep where
  just :: DinoTypeRep a -> DinoTypeRep (Maybe a)
just DinoTypeRep a
t            = DinoTypeRep a
-> (DinoType a => DinoTypeRep (Maybe a)) -> DinoTypeRep (Maybe a)
forall a b. DinoTypeRep a -> (DinoType a => b) -> b
withType DinoTypeRep a
t DinoType a => DinoTypeRep (Maybe a)
forall a. (BuiltIn a ~ 'False, DinoType a) => DinoTypeRep a
OtherType
  cases :: [DinoTypeRep Bool :-> DinoTypeRep a]
-> (Otherwise :-> DinoTypeRep a) -> DinoTypeRep a
cases [DinoTypeRep Bool :-> DinoTypeRep a]
_ (Otherwise
_ :-> DinoTypeRep a
t) = DinoTypeRep a
t
  partial_cases :: [DinoTypeRep Bool :-> DinoTypeRep a] -> DinoTypeRep a
partial_cases     = [DinoTypeRep Bool :-> DinoTypeRep a] -> DinoTypeRep a
forall (e :: * -> *) a.
(CondExpFO e, HasCallStack) =>
[e Bool :-> e a] -> e a
default_partial_cases

instance CondExp DinoTypeRep where
  maybe :: DinoTypeRep b
-> (DinoTypeRep a -> DinoTypeRep b)
-> DinoTypeRep (Maybe a)
-> DinoTypeRep b
maybe DinoTypeRep b
t DinoTypeRep a -> DinoTypeRep b
_ DinoTypeRep (Maybe a)
_ = DinoTypeRep b
t

instance ListExpFO DinoTypeRep where
  range :: DinoTypeRep a -> DinoTypeRep a -> DinoTypeRep [a]
range DinoTypeRep a
t DinoTypeRep a
_  = DinoTypeRep a -> DinoTypeRep [a]
forall a. DinoTypeRep a -> DinoTypeRep [a]
ListType DinoTypeRep a
t
  list :: [DinoTypeRep a] -> DinoTypeRep [a]
list [DinoTypeRep a]
_     = DinoTypeRep [a]
forall a. DinoType a => DinoTypeRep a
dinoTypeRep
  headE :: DinoTypeRep [a] -> DinoTypeRep (Maybe a)
headE      = (\DinoTypeRep a
t -> DinoTypeRep a
-> (DinoType a => DinoTypeRep (Maybe a)) -> DinoTypeRep (Maybe a)
forall a b. DinoTypeRep a -> (DinoType a => b) -> b
withType DinoTypeRep a
t DinoType a => DinoTypeRep (Maybe a)
forall a. (BuiltIn a ~ 'False, DinoType a) => DinoTypeRep a
OtherType) (DinoTypeRep a -> DinoTypeRep (Maybe a))
-> (DinoTypeRep [a] -> DinoTypeRep a)
-> DinoTypeRep [a]
-> DinoTypeRep (Maybe a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DinoTypeRep [a] -> DinoTypeRep a
forall a. DinoTypeRep [a] -> DinoTypeRep a
listTypeElem
  append :: DinoTypeRep [a] -> DinoTypeRep [a] -> DinoTypeRep [a]
append DinoTypeRep [a]
t DinoTypeRep [a]
_ = DinoTypeRep [a]
t

instance ListExp DinoTypeRep where
  mapE :: (DinoTypeRep a -> DinoTypeRep b)
-> DinoTypeRep [a] -> DinoTypeRep [b]
mapE DinoTypeRep a -> DinoTypeRep b
f       = DinoTypeRep b -> DinoTypeRep [b]
forall a. DinoTypeRep a -> DinoTypeRep [a]
ListType (DinoTypeRep b -> DinoTypeRep [b])
-> (DinoTypeRep [a] -> DinoTypeRep b)
-> DinoTypeRep [a]
-> DinoTypeRep [b]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DinoTypeRep a -> DinoTypeRep b
f (DinoTypeRep a -> DinoTypeRep b)
-> (DinoTypeRep [a] -> DinoTypeRep a)
-> DinoTypeRep [a]
-> DinoTypeRep b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DinoTypeRep [a] -> DinoTypeRep a
forall a. DinoTypeRep [a] -> DinoTypeRep a
listTypeElem
  dropWhileE :: (DinoTypeRep a -> DinoTypeRep Bool)
-> DinoTypeRep [a] -> DinoTypeRep [a]
dropWhileE DinoTypeRep a -> DinoTypeRep Bool
_ = DinoTypeRep [a] -> DinoTypeRep [a]
forall a. a -> a
id
  foldE :: (DinoTypeRep a -> DinoTypeRep b -> DinoTypeRep a)
-> DinoTypeRep a -> DinoTypeRep [b] -> DinoTypeRep a
foldE DinoTypeRep a -> DinoTypeRep b -> DinoTypeRep a
_ DinoTypeRep a
t DinoTypeRep [b]
_  = DinoTypeRep a
t
  -- Note: `mapE` has to build the body before returning. This leads to
  -- quadratic complexity for nested maps.

instance TupleExp DinoTypeRep where
  pair :: DinoTypeRep a -> DinoTypeRep b -> DinoTypeRep (a, b)
pair                = DinoTypeRep a -> DinoTypeRep b -> DinoTypeRep (a, b)
forall a b. DinoTypeRep a -> DinoTypeRep b -> DinoTypeRep (a, b)
PairType
  fstE :: DinoTypeRep (a, b) -> DinoTypeRep a
fstE (PairType DinoTypeRep a
t DinoTypeRep b
_) = DinoTypeRep a
DinoTypeRep a
t
  sndE :: DinoTypeRep (a, b) -> DinoTypeRep b
sndE (PairType DinoTypeRep a
_ DinoTypeRep b
t) = DinoTypeRep b
DinoTypeRep b
t

instance LetExp DinoTypeRep where
  letE :: Text
-> DinoTypeRep a
-> (DinoTypeRep a -> DinoTypeRep b)
-> DinoTypeRep b
letE Text
_ DinoTypeRep a
t DinoTypeRep a -> DinoTypeRep b
body = DinoTypeRep a -> DinoTypeRep b
body DinoTypeRep a
t
  -- Note: `letE` has to build the body before returning. This leads to
  -- quadratic complexity for nested maps.

instance FieldExp DinoTypeRep where
  getField :: proxy f -> DinoTypeRep r -> DinoTypeRep a
getField proxy f
_ DinoTypeRep r
_ = DinoTypeRep a
forall a. DinoType a => DinoTypeRep a
dinoTypeRep

instance AnnExp ann DinoTypeRep

instance AssertExp DinoTypeRep



--------------------------------------------------------------------------------
-- * Monadic interpretation
--------------------------------------------------------------------------------

instance ConstExp Identity
instance NumExp Identity
instance FracExp Identity
instance LogicExp Identity
instance CompareExp Identity
instance CondExpFO Identity
instance CondExp Identity
instance ListExpFO Identity
instance ListExp Identity
instance TupleExp Identity
instance LetExp Identity
instance FieldExp Identity
instance AnnExp ann Identity
-- | Ignoring assertion for efficiency
instance AssertExp Identity

instance ConstExp Maybe
instance NumExp Maybe
instance FracExp Maybe
instance LogicExp Maybe
instance CompareExp Maybe
instance CondExpFO Maybe
instance CondExp Maybe
instance ListExpFO Maybe
instance ListExp Maybe
instance TupleExp Maybe
instance LetExp Maybe
instance FieldExp Maybe
instance AnnExp ann Maybe
-- | Ignoring assertion for efficiency
instance AssertExp Maybe

instance ConstExp (Either e)
instance NumExp (Either e)
instance FracExp (Either e)
instance LogicExp (Either e)
instance CompareExp (Either e)
instance CondExpFO (Either e)
instance CondExp (Either e)
instance ListExpFO (Either e)
instance ListExp (Either e)
instance TupleExp (Either e)
instance LetExp (Either e)
instance FieldExp (Either e)
instance AnnExp ann (Either e)
-- | Ignoring assertion for efficiency
instance AssertExp (Either e)

instance Monad m => ConstExp (ExceptT e m)
instance Monad m => NumExp (ExceptT e m)
instance Monad m => FracExp (ExceptT e m)
instance Monad m => LogicExp (ExceptT e m)
instance Monad m => CompareExp (ExceptT e m)
instance Monad m => CondExpFO (ExceptT e m)
instance Monad m => CondExp (ExceptT e m)
instance Monad m => ListExpFO (ExceptT e m)
instance Monad m => ListExp (ExceptT e m)
instance Monad m => TupleExp (ExceptT e m)
instance Monad m => LetExp (ExceptT e m)
instance Monad m => FieldExp (ExceptT e m)
instance            AnnExp ann (ExceptT e m)
-- | Ignoring assertion for efficiency
instance            AssertExp (ExceptT e m)

instance Applicative m => ConstExp (ReaderT env m)
instance Applicative m => NumExp (ReaderT env m)
instance Applicative m => FracExp (ReaderT env m)
instance Applicative m => LogicExp (ReaderT env m)
instance Applicative m => CompareExp (ReaderT env m)
instance Monad m       => CondExpFO (ReaderT env m)
instance Monad m       => CondExp (ReaderT env m)
instance Monad m       => ListExpFO (ReaderT env m)
instance Monad m       => ListExp (ReaderT env m)
instance Monad m       => TupleExp (ReaderT env m)
instance Monad m       => LetExp (ReaderT env m)
instance Monad m       => FieldExp (ReaderT env m)
instance                  AnnExp ann (ReaderT env m)
-- | Ignoring assertion for efficiency
instance                  AssertExp (ReaderT env m)

instance (Monoid t, Applicative m) => ConstExp (WriterT t m)
instance (Monoid t, Applicative m) => NumExp (WriterT t m)
instance (Monoid t, Applicative m) => FracExp (WriterT t m)
instance (Monoid t, Applicative m) => LogicExp (WriterT t m)
instance (Monoid t, Applicative m) => CompareExp (WriterT t m)
instance (Monoid t, Monad m)       => CondExpFO (WriterT t m)
instance (Monoid t, Monad m)       => CondExp (WriterT t m)
instance (Monoid t, Monad m)       => ListExpFO (WriterT t m)
instance (Monoid t, Monad m)       => ListExp (WriterT t m)
instance (Monoid t, Monad m)       => TupleExp (WriterT t m)
instance (Monoid t, Monad m)       => LetExp (WriterT t m)
instance (Monoid t, Monad m)       => FieldExp (WriterT t m)
instance                              AnnExp ann (WriterT t m)
-- | Ignoring assertion for efficiency
instance                              AssertExp (WriterT t m)

-- | Pure evaluation
eval :: Exp Identity a -> a
eval :: Exp Identity a -> a
eval = Exp Identity a -> a
coerce

-- | Functorial evaluation
--
-- Can, for example, have the type
--
-- @`evalF` :: `Exp` `Maybe` a -> `Maybe` a@
evalF :: Exp f a -> f a
evalF :: Exp f a -> f a
evalF = Exp f a -> f a
coerce



--------------------------------------------------------------------------------
-- * Folding
--------------------------------------------------------------------------------

-- | A folding interpretation
--
-- Instances of expression classes work by monoidal folding over @e@ (see
-- 'foldMonoid').
newtype Fold e a = Fold {Fold e a -> e
fold :: e}
  deriving (Fold e a -> Fold e a -> Bool
(Fold e a -> Fold e a -> Bool)
-> (Fold e a -> Fold e a -> Bool) -> Eq (Fold e a)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall e a. Eq e => Fold e a -> Fold e a -> Bool
/= :: Fold e a -> Fold e a -> Bool
$c/= :: forall e a. Eq e => Fold e a -> Fold e a -> Bool
== :: Fold e a -> Fold e a -> Bool
$c== :: forall e a. Eq e => Fold e a -> Fold e a -> Bool
Eq, Int -> Fold e a -> ShowS
[Fold e a] -> ShowS
Fold e a -> String
(Int -> Fold e a -> ShowS)
-> (Fold e a -> String) -> ([Fold e a] -> ShowS) -> Show (Fold e a)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall e a. Show e => Int -> Fold e a -> ShowS
forall e a. Show e => [Fold e a] -> ShowS
forall e a. Show e => Fold e a -> String
showList :: [Fold e a] -> ShowS
$cshowList :: forall e a. Show e => [Fold e a] -> ShowS
show :: Fold e a -> String
$cshow :: forall e a. Show e => Fold e a -> String
showsPrec :: Int -> Fold e a -> ShowS
$cshowsPrec :: forall e a. Show e => Int -> Fold e a -> ShowS
Show, (a -> b) -> Fold e a -> Fold e b
(forall a b. (a -> b) -> Fold e a -> Fold e b)
-> (forall a b. a -> Fold e b -> Fold e a) -> Functor (Fold e)
forall a b. a -> Fold e b -> Fold e a
forall a b. (a -> b) -> Fold e a -> Fold e b
forall e a b. a -> Fold e b -> Fold e a
forall e a b. (a -> b) -> Fold e a -> Fold e b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: a -> Fold e b -> Fold e a
$c<$ :: forall e a b. a -> Fold e b -> Fold e a
fmap :: (a -> b) -> Fold e a -> Fold e b
$cfmap :: forall e a b. (a -> b) -> Fold e a -> Fold e b
Functor, b -> Fold e a -> Fold e a
NonEmpty (Fold e a) -> Fold e a
Fold e a -> Fold e a -> Fold e a
(Fold e a -> Fold e a -> Fold e a)
-> (NonEmpty (Fold e a) -> Fold e a)
-> (forall b. Integral b => b -> Fold e a -> Fold e a)
-> Semigroup (Fold e a)
forall b. Integral b => b -> Fold e a -> Fold e a
forall a.
(a -> a -> a)
-> (NonEmpty a -> a)
-> (forall b. Integral b => b -> a -> a)
-> Semigroup a
forall e a. Semigroup e => NonEmpty (Fold e a) -> Fold e a
forall e a. Semigroup e => Fold e a -> Fold e a -> Fold e a
forall e a b.
(Semigroup e, Integral b) =>
b -> Fold e a -> Fold e a
stimes :: b -> Fold e a -> Fold e a
$cstimes :: forall e a b.
(Semigroup e, Integral b) =>
b -> Fold e a -> Fold e a
sconcat :: NonEmpty (Fold e a) -> Fold e a
$csconcat :: forall e a. Semigroup e => NonEmpty (Fold e a) -> Fold e a
<> :: Fold e a -> Fold e a -> Fold e a
$c<> :: forall e a. Semigroup e => Fold e a -> Fold e a -> Fold e a
Semigroup, Semigroup (Fold e a)
Fold e a
Semigroup (Fold e a)
-> Fold e a
-> (Fold e a -> Fold e a -> Fold e a)
-> ([Fold e a] -> Fold e a)
-> Monoid (Fold e a)
[Fold e a] -> Fold e a
Fold e a -> Fold e a -> Fold e a
forall a.
Semigroup a -> a -> (a -> a -> a) -> ([a] -> a) -> Monoid a
forall e a. Monoid e => Semigroup (Fold e a)
forall e a. Monoid e => Fold e a
forall e a. Monoid e => [Fold e a] -> Fold e a
forall e a. Monoid e => Fold e a -> Fold e a -> Fold e a
mconcat :: [Fold e a] -> Fold e a
$cmconcat :: forall e a. Monoid e => [Fold e a] -> Fold e a
mappend :: Fold e a -> Fold e a -> Fold e a
$cmappend :: forall e a. Monoid e => Fold e a -> Fold e a -> Fold e a
mempty :: Fold e a
$cmempty :: forall e a. Monoid e => Fold e a
$cp1Monoid :: forall e a. Monoid e => Semigroup (Fold e a)
Monoid)

instance Monoid e => Applicative (Fold e) where
  pure :: a -> Fold e a
pure = a -> Fold e a
forall a. Monoid a => a
mempty
  Fold e (a -> b)
f <*> :: Fold e (a -> b) -> Fold e a -> Fold e b
<*> Fold e a
a = e -> Fold e b
forall e a. e -> Fold e a
Fold (Fold e (a -> b) -> e
forall e a. Fold e a -> e
fold Fold e (a -> b)
f e -> e -> e
forall a. Semigroup a => a -> a -> a
<> Fold e a -> e
forall e a. Fold e a -> e
fold Fold e a
a)

-- | N-ary folding functions
class FoldN f e | f -> e where
  -- | @`foldN` e (*)@  returns an n-ary function of the following form:
  --
  -- > \(Fold a) (Fold b) ... (Fold x) -> Fold (e * a * b * ... x)
  --
  -- (here @*@ denotes any binary operator, and it's assumed to be right-
  -- associative.)
  foldN :: e -> (e -> e -> e) -> f

instance FoldN (Fold e a) e where
  foldN :: e -> (e -> e -> e) -> Fold e a
foldN e
e0 e -> e -> e
_ = e -> Fold e a
forall e a. e -> Fold e a
Fold e
e0

instance FoldN f e => FoldN (Fold e a -> f) e where
  foldN :: e -> (e -> e -> e) -> Fold e a -> f
foldN e
e0 e -> e -> e
conc = \(Fold e
e) -> e -> (e -> e -> e) -> f
forall f e. FoldN f e => e -> (e -> e -> e) -> f
foldN (e -> e -> e
conc e
e0 e
e) e -> e -> e
conc

-- | @'foldMonoid' returns an n-ary function of the following form:
--
-- > \(Fold a) (Fold b) ... (Fold x) -> Fold (mempty <> a <> b <> ... x)
--
-- where 'mempty' and '<>' are the methods of the 'Monoid' class.
foldMonoid :: (FoldN f e, Monoid e) => f
foldMonoid :: f
foldMonoid = e -> (e -> e -> e) -> f
forall f e. FoldN f e => e -> (e -> e -> e) -> f
foldN e
forall a. Monoid a => a
mempty e -> e -> e
forall a. Monoid a => a -> a -> a
mappend

instance Monoid e => ConstExp   (Fold e)
instance Monoid e => NumExp     (Fold e)
instance Monoid e => FracExp    (Fold e)
instance Monoid e => LogicExp   (Fold e)
instance Monoid e => CompareExp (Fold e)
instance Monoid e => ListExpFO  (Fold e)
instance Monoid e => TupleExp   (Fold e)
instance Monoid e => FieldExp   (Fold e)
instance             AnnExp ann (Fold e)

-- | Interprets all branches
instance Monoid e => CondExpFO (Fold e) where
  cases :: [Fold e Bool :-> Fold e a] -> (Otherwise :-> Fold e a) -> Fold e a
cases [Fold e Bool :-> Fold e a]
cs (Otherwise
Otherwise :-> Fold e a
d) =
    e -> Fold e a
forall e a. e -> Fold e a
Fold (e -> Fold e a) -> e -> Fold e a
forall a b. (a -> b) -> a -> b
$ [e] -> e
forall a. Monoid a => [a] -> a
mconcat ([e] -> e) -> [e] -> e
forall a b. (a -> b) -> a -> b
$ [[e]] -> [e]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [[Fold e Bool -> e
forall e a. Fold e a -> e
fold Fold e Bool
c, Fold e a -> e
forall e a. Fold e a -> e
fold Fold e a
a] | (Fold e Bool
c :-> Fold e a
a) <- [Fold e Bool :-> Fold e a]
cs] [e] -> [e] -> [e]
forall a. [a] -> [a] -> [a]
++ [Fold e a -> e
forall e a. Fold e a -> e
fold Fold e a
d]

  partial_cases :: [Fold e Bool :-> Fold e a] -> Fold e a
partial_cases [Fold e Bool :-> Fold e a]
cs =
    e -> Fold e a
forall e a. e -> Fold e a
Fold (e -> Fold e a) -> e -> Fold e a
forall a b. (a -> b) -> a -> b
$ [e] -> e
forall a. Monoid a => [a] -> a
mconcat ([e] -> e) -> [e] -> e
forall a b. (a -> b) -> a -> b
$ [[e]] -> [e]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [[Fold e Bool -> e
forall e a. Fold e a -> e
fold Fold e Bool
c, Fold e a -> e
forall e a. Fold e a -> e
fold Fold e a
a] | (Fold e Bool
c :-> Fold e a
a) <- [Fold e Bool :-> Fold e a]
cs]

-- | Interprets all branches
instance Monoid e => CondExp (Fold e) where
  maybe :: Fold e b -> (Fold e a -> Fold e b) -> Fold e (Maybe a) -> Fold e b
maybe Fold e b
n Fold e a -> Fold e b
j Fold e (Maybe a)
m = Fold e (Maybe a) -> Fold e b
coerce Fold e (Maybe a)
m Fold e b -> Fold e b -> Fold e b
forall a. Semigroup a => a -> a -> a
<> Fold e b -> Fold e b
coerce Fold e b
n Fold e b -> Fold e b -> Fold e b
forall a. Semigroup a => a -> a -> a
<> Fold e b -> Fold e b
coerce (Fold e a -> Fold e b
j Fold e a
forall a. Monoid a => a
mempty)

instance Monoid e => ListExp (Fold e) where
  mapE :: (Fold e a -> Fold e b) -> Fold e [a] -> Fold e [b]
mapE Fold e a -> Fold e b
f Fold e [a]
as       = Fold e [a] -> Fold e [b]
coerce Fold e [a]
as Fold e [b] -> Fold e [b] -> Fold e [b]
forall a. Semigroup a => a -> a -> a
<> Fold e b -> Fold e [b]
coerce (Fold e a -> Fold e b
f Fold e a
forall a. Monoid a => a
mempty)
  dropWhileE :: (Fold e a -> Fold e Bool) -> Fold e [a] -> Fold e [a]
dropWhileE Fold e a -> Fold e Bool
p Fold e [a]
as = Fold e [a] -> Fold e [a]
coerce Fold e [a]
as Fold e [a] -> Fold e [a] -> Fold e [a]
forall a. Semigroup a => a -> a -> a
<> Fold e Bool -> Fold e [a]
coerce (Fold e a -> Fold e Bool
p Fold e a
forall a. Monoid a => a
mempty)
  foldE :: (Fold e a -> Fold e b -> Fold e a)
-> Fold e a -> Fold e [b] -> Fold e a
foldE Fold e a -> Fold e b -> Fold e a
f Fold e a
a Fold e [b]
as    = Fold e a -> Fold e a
coerce Fold e a
a Fold e a -> Fold e a -> Fold e a
forall a. Semigroup a => a -> a -> a
<> Fold e [b] -> Fold e a
coerce Fold e [b]
as Fold e a -> Fold e a -> Fold e a
forall a. Semigroup a => a -> a -> a
<> Fold e a -> Fold e a
coerce (Fold e a -> Fold e b -> Fold e a
f Fold e a
forall a. Monoid a => a
mempty Fold e b
forall a. Monoid a => a
mempty)

instance Monoid e => LetExp (Fold e) where
  letE :: Text -> Fold e a -> (Fold e a -> Fold e b) -> Fold e b
letE Text
_ Fold e a
a Fold e a -> Fold e b
f = Fold e a -> Fold e b
coerce Fold e a
a Fold e b -> Fold e b -> Fold e b
forall a. Semigroup a => a -> a -> a
<> Fold e a -> Fold e b
f Fold e a
forall a. Monoid a => a
mempty

-- | Ignoring assertion
instance AssertExp (Fold e)

instance Monoid e => VarExp (Fold e) where
  varE :: Text -> Fold e a
varE Text
_ = Fold e a
forall a. Monoid a => a
mempty

instance Semigroup e => CondIntensional (Fold e) where
  maybeI :: Text -> Fold e b -> Fold e b -> Fold e (Maybe a) -> Fold e b
maybeI Text
_ Fold e b
n Fold e b
j Fold e (Maybe a)
m = Fold e (Maybe a) -> Fold e b
coerce Fold e (Maybe a)
m Fold e b -> Fold e b -> Fold e b
forall a. Semigroup a => a -> a -> a
<> Fold e b -> Fold e b
coerce Fold e b
n Fold e b -> Fold e b -> Fold e b
forall a. Semigroup a => a -> a -> a
<> Fold e b -> Fold e b
coerce Fold e b
j

instance Semigroup e => ListIntensional (Fold e) where
  mapI :: Text -> Fold e b -> Fold e [a] -> Fold e [b]
mapI Text
_ Fold e b
b Fold e [a]
as       = Fold e [a] -> Fold e [b]
coerce Fold e [a]
as Fold e [b] -> Fold e [b] -> Fold e [b]
forall a. Semigroup a => a -> a -> a
<> Fold e b -> Fold e [b]
coerce Fold e b
b
  dropWhileI :: Text -> Fold e Bool -> Fold e [a] -> Fold e [a]
dropWhileI Text
_ Fold e Bool
b Fold e [a]
as = Fold e [a] -> Fold e [a]
coerce Fold e [a]
as Fold e [a] -> Fold e [a] -> Fold e [a]
forall a. Semigroup a => a -> a -> a
<> Fold e Bool -> Fold e [a]
coerce Fold e Bool
b
  foldI :: Text -> Text -> Fold e a -> Fold e a -> Fold e [b] -> Fold e a
foldI Text
_ Text
_ Fold e a
b Fold e a
a Fold e [b]
as  = Fold e a -> Fold e a
coerce Fold e a
a Fold e a -> Fold e a -> Fold e a
forall a. Semigroup a => a -> a -> a
<> Fold e [b] -> Fold e a
coerce Fold e [b]
as Fold e a -> Fold e a -> Fold e a
forall a. Semigroup a => a -> a -> a
<> Fold e a -> Fold e a
coerce Fold e a
b

instance Semigroup e => LetIntensional (Fold e) where
  letI :: Text -> Fold e a -> Fold e b -> Fold e b
letI Text
_ Fold e a
a Fold e b
b = Fold e a -> Fold e b
coerce Fold e a
a Fold e b -> Fold e b -> Fold e b
forall a. Semigroup a => a -> a -> a
<> Fold e b -> Fold e b
coerce Fold e b
b



--------------------------------------------------------------------------------
-- * Product of interpretations
--------------------------------------------------------------------------------

-- | Product of two interpretations
--
-- The product is used to run two interpretations in parallel. Note that there
-- are no instances for HOS classes. Instead, use @`Intensional` (e1 :×: e2)@ in
-- order to derive an interpretation of HOS classes for products.
data (e1 :×: e2) a = (:×:)
  { (:×:) e1 e2 a -> e1 a
prodFst :: e1 a
  , (:×:) e1 e2 a -> e2 a
prodSnd :: e2 a
  }

mkProd ::
     (lang e1, lang e2)
  => proxy lang
  -> (forall e. lang e => e a)
  -> (e1 :×: e2) a
mkProd :: proxy lang
-> (forall (e :: * -> *). lang e => e a) -> (:×:) e1 e2 a
mkProd proxy lang
_ forall (e :: * -> *). lang e => e a
e = e1 a
forall (e :: * -> *). lang e => e a
e e1 a -> e2 a -> (:×:) e1 e2 a
forall (e1 :: * -> *) (e2 :: * -> *) a.
e1 a -> e2 a -> (:×:) e1 e2 a
:×: e2 a
forall (e :: * -> *). lang e => e a
e

liftProd ::
     (lang e1, lang e2)
  => proxy lang
  -> (forall e. lang e => e a -> e b)
  -> (e1 :×: e2) a
  -> (e1 :×: e2) b
liftProd :: proxy lang
-> (forall (e :: * -> *). lang e => e a -> e b)
-> (:×:) e1 e2 a
-> (:×:) e1 e2 b
liftProd proxy lang
_ forall (e :: * -> *). lang e => e a -> e b
f (e1 a
a1 :×: e2 a
a2) = e1 a -> e1 b
forall (e :: * -> *). lang e => e a -> e b
f e1 a
a1 e1 b -> e2 b -> (:×:) e1 e2 b
forall (e1 :: * -> *) (e2 :: * -> *) a.
e1 a -> e2 a -> (:×:) e1 e2 a
:×: e2 a -> e2 b
forall (e :: * -> *). lang e => e a -> e b
f e2 a
a2

liftProd2 ::
     (lang e1, lang e2)
  => proxy lang
  -> (forall e. lang e => e a -> e b -> e c)
  -> (e1 :×: e2) a
  -> (e1 :×: e2) b
  -> (e1 :×: e2) c
liftProd2 :: proxy lang
-> (forall (e :: * -> *). lang e => e a -> e b -> e c)
-> (:×:) e1 e2 a
-> (:×:) e1 e2 b
-> (:×:) e1 e2 c
liftProd2 proxy lang
_ forall (e :: * -> *). lang e => e a -> e b -> e c
f (e1 a
a1 :×: e2 a
a2) (e1 b
b1 :×: e2 b
b2) = e1 a -> e1 b -> e1 c
forall (e :: * -> *). lang e => e a -> e b -> e c
f e1 a
a1 e1 b
b1 e1 c -> e2 c -> (:×:) e1 e2 c
forall (e1 :: * -> *) (e2 :: * -> *) a.
e1 a -> e2 a -> (:×:) e1 e2 a
:×: e2 a -> e2 b -> e2 c
forall (e :: * -> *). lang e => e a -> e b -> e c
f e2 a
a2 e2 b
b2

liftProd3 ::
     (lang e1, lang e2)
  => proxy lang
  -> (forall e. lang e => e a -> e b -> e c -> e d)
  -> (e1 :×: e2) a
  -> (e1 :×: e2) b
  -> (e1 :×: e2) c
  -> (e1 :×: e2) d
liftProd3 :: proxy lang
-> (forall (e :: * -> *). lang e => e a -> e b -> e c -> e d)
-> (:×:) e1 e2 a
-> (:×:) e1 e2 b
-> (:×:) e1 e2 c
-> (:×:) e1 e2 d
liftProd3 proxy lang
_ forall (e :: * -> *). lang e => e a -> e b -> e c -> e d
f (e1 a
a1 :×: e2 a
a2) (e1 b
b1 :×: e2 b
b2) (e1 c
c1 :×: e2 c
c2) = e1 a -> e1 b -> e1 c -> e1 d
forall (e :: * -> *). lang e => e a -> e b -> e c -> e d
f e1 a
a1 e1 b
b1 e1 c
c1 e1 d -> e2 d -> (:×:) e1 e2 d
forall (e1 :: * -> *) (e2 :: * -> *) a.
e1 a -> e2 a -> (:×:) e1 e2 a
:×: e2 a -> e2 b -> e2 c -> e2 d
forall (e :: * -> *). lang e => e a -> e b -> e c -> e d
f e2 a
a2 e2 b
b2 e2 c
c2

instance (ConstExp e1, ConstExp e2) => ConstExp (e1 :×: e2) where
  lit :: a -> (:×:) e1 e2 a
lit a
a = Proxy ConstExp
-> (forall (e :: * -> *). ConstExp e => e a) -> (:×:) e1 e2 a
forall (lang :: (* -> *) -> Constraint) (e1 :: * -> *)
       (e2 :: * -> *) (proxy :: ((* -> *) -> Constraint) -> *) a.
(lang e1, lang e2) =>
proxy lang
-> (forall (e :: * -> *). lang e => e a) -> (:×:) e1 e2 a
mkProd (Proxy ConstExp
forall k (t :: k). Proxy t
Proxy @ConstExp) (a -> e a
forall (e :: * -> *) a. (ConstExp e, DinoType a) => a -> e a
lit a
a)

instance (NumExp e1, NumExp e2) => NumExp (e1 :×: e2) where
  add :: (:×:) e1 e2 a -> (:×:) e1 e2 a -> (:×:) e1 e2 a
add          = Proxy NumExp
-> (forall (e :: * -> *). NumExp e => e a -> e a -> e a)
-> (:×:) e1 e2 a
-> (:×:) e1 e2 a
-> (:×:) e1 e2 a
forall (lang :: (* -> *) -> Constraint) (e1 :: * -> *)
       (e2 :: * -> *) (proxy :: ((* -> *) -> Constraint) -> *) a b c.
(lang e1, lang e2) =>
proxy lang
-> (forall (e :: * -> *). lang e => e a -> e b -> e c)
-> (:×:) e1 e2 a
-> (:×:) e1 e2 b
-> (:×:) e1 e2 c
liftProd2 (Proxy NumExp
forall k (t :: k). Proxy t
Proxy @NumExp) forall (e :: * -> *). NumExp e => e a -> e a -> e a
forall (e :: * -> *) a. (NumExp e, Num a) => e a -> e a -> e a
add
  sub :: (:×:) e1 e2 a -> (:×:) e1 e2 a -> (:×:) e1 e2 a
sub          = Proxy NumExp
-> (forall (e :: * -> *). NumExp e => e a -> e a -> e a)
-> (:×:) e1 e2 a
-> (:×:) e1 e2 a
-> (:×:) e1 e2 a
forall (lang :: (* -> *) -> Constraint) (e1 :: * -> *)
       (e2 :: * -> *) (proxy :: ((* -> *) -> Constraint) -> *) a b c.
(lang e1, lang e2) =>
proxy lang
-> (forall (e :: * -> *). lang e => e a -> e b -> e c)
-> (:×:) e1 e2 a
-> (:×:) e1 e2 b
-> (:×:) e1 e2 c
liftProd2 (Proxy NumExp
forall k (t :: k). Proxy t
Proxy @NumExp) forall (e :: * -> *). NumExp e => e a -> e a -> e a
forall (e :: * -> *) a. (NumExp e, Num a) => e a -> e a -> e a
sub
  mul :: (:×:) e1 e2 a -> (:×:) e1 e2 a -> (:×:) e1 e2 a
mul          = Proxy NumExp
-> (forall (e :: * -> *). NumExp e => e a -> e a -> e a)
-> (:×:) e1 e2 a
-> (:×:) e1 e2 a
-> (:×:) e1 e2 a
forall (lang :: (* -> *) -> Constraint) (e1 :: * -> *)
       (e2 :: * -> *) (proxy :: ((* -> *) -> Constraint) -> *) a b c.
(lang e1, lang e2) =>
proxy lang
-> (forall (e :: * -> *). lang e => e a -> e b -> e c)
-> (:×:) e1 e2 a
-> (:×:) e1 e2 b
-> (:×:) e1 e2 c
liftProd2 (Proxy NumExp
forall k (t :: k). Proxy t
Proxy @NumExp) forall (e :: * -> *). NumExp e => e a -> e a -> e a
forall (e :: * -> *) a. (NumExp e, Num a) => e a -> e a -> e a
mul
  absE :: (:×:) e1 e2 a -> (:×:) e1 e2 a
absE         = Proxy NumExp
-> (forall (e :: * -> *). NumExp e => e a -> e a)
-> (:×:) e1 e2 a
-> (:×:) e1 e2 a
forall (lang :: (* -> *) -> Constraint) (e1 :: * -> *)
       (e2 :: * -> *) (proxy :: ((* -> *) -> Constraint) -> *) a b.
(lang e1, lang e2) =>
proxy lang
-> (forall (e :: * -> *). lang e => e a -> e b)
-> (:×:) e1 e2 a
-> (:×:) e1 e2 b
liftProd  (Proxy NumExp
forall k (t :: k). Proxy t
Proxy @NumExp) forall (e :: * -> *). NumExp e => e a -> e a
forall (e :: * -> *) a. (NumExp e, Num a) => e a -> e a
absE
  signE :: (:×:) e1 e2 a -> (:×:) e1 e2 a
signE        = Proxy NumExp
-> (forall (e :: * -> *). NumExp e => e a -> e a)
-> (:×:) e1 e2 a
-> (:×:) e1 e2 a
forall (lang :: (* -> *) -> Constraint) (e1 :: * -> *)
       (e2 :: * -> *) (proxy :: ((* -> *) -> Constraint) -> *) a b.
(lang e1, lang e2) =>
proxy lang
-> (forall (e :: * -> *). lang e => e a -> e b)
-> (:×:) e1 e2 a
-> (:×:) e1 e2 b
liftProd  (Proxy NumExp
forall k (t :: k). Proxy t
Proxy @NumExp) forall (e :: * -> *). NumExp e => e a -> e a
forall (e :: * -> *) a. (NumExp e, Num a) => e a -> e a
signE
  fromIntegral :: (:×:) e1 e2 a -> (:×:) e1 e2 b
fromIntegral = Proxy NumExp
-> (forall (e :: * -> *). NumExp e => e a -> e b)
-> (:×:) e1 e2 a
-> (:×:) e1 e2 b
forall (lang :: (* -> *) -> Constraint) (e1 :: * -> *)
       (e2 :: * -> *) (proxy :: ((* -> *) -> Constraint) -> *) a b.
(lang e1, lang e2) =>
proxy lang
-> (forall (e :: * -> *). lang e => e a -> e b)
-> (:×:) e1 e2 a
-> (:×:) e1 e2 b
liftProd  (Proxy NumExp
forall k (t :: k). Proxy t
Proxy @NumExp) forall (e :: * -> *). NumExp e => e a -> e b
forall (e :: * -> *) a b.
(NumExp e, Integral a, DinoType b, Num b) =>
e a -> e b
fromIntegral
  floor :: (:×:) e1 e2 a -> (:×:) e1 e2 b
floor        = Proxy NumExp
-> (forall (e :: * -> *). NumExp e => e a -> e b)
-> (:×:) e1 e2 a
-> (:×:) e1 e2 b
forall (lang :: (* -> *) -> Constraint) (e1 :: * -> *)
       (e2 :: * -> *) (proxy :: ((* -> *) -> Constraint) -> *) a b.
(lang e1, lang e2) =>
proxy lang
-> (forall (e :: * -> *). lang e => e a -> e b)
-> (:×:) e1 e2 a
-> (:×:) e1 e2 b
liftProd  (Proxy NumExp
forall k (t :: k). Proxy t
Proxy @NumExp) forall (e :: * -> *). NumExp e => e a -> e b
forall (e :: * -> *) a b.
(NumExp e, RealFrac a, DinoType b, Integral b) =>
e a -> e b
floor
  truncate :: (:×:) e1 e2 a -> (:×:) e1 e2 b
truncate     = Proxy NumExp
-> (forall (e :: * -> *). NumExp e => e a -> e b)
-> (:×:) e1 e2 a
-> (:×:) e1 e2 b
forall (lang :: (* -> *) -> Constraint) (e1 :: * -> *)
       (e2 :: * -> *) (proxy :: ((* -> *) -> Constraint) -> *) a b.
(lang e1, lang e2) =>
proxy lang
-> (forall (e :: * -> *). lang e => e a -> e b)
-> (:×:) e1 e2 a
-> (:×:) e1 e2 b
liftProd  (Proxy NumExp
forall k (t :: k). Proxy t
Proxy @NumExp) forall (e :: * -> *). NumExp e => e a -> e b
forall (e :: * -> *) a b.
(NumExp e, RealFrac a, DinoType b, Integral b) =>
e a -> e b
truncate
  roundN :: Int -> (:×:) e1 e2 a -> (:×:) e1 e2 a
roundN Int
n     = Proxy NumExp
-> (forall (e :: * -> *). NumExp e => e a -> e a)
-> (:×:) e1 e2 a
-> (:×:) e1 e2 a
forall (lang :: (* -> *) -> Constraint) (e1 :: * -> *)
       (e2 :: * -> *) (proxy :: ((* -> *) -> Constraint) -> *) a b.
(lang e1, lang e2) =>
proxy lang
-> (forall (e :: * -> *). lang e => e a -> e b)
-> (:×:) e1 e2 a
-> (:×:) e1 e2 b
liftProd  (Proxy NumExp
forall k (t :: k). Proxy t
Proxy @NumExp) (Int -> e a -> e a
forall (e :: * -> *) a. (NumExp e, RealFrac a) => Int -> e a -> e a
roundN Int
n)

instance (FracExp e1, FracExp e2) => FracExp (e1 :×: e2) where
  fdiv :: (:×:) e1 e2 a -> (:×:) e1 e2 a -> (:×:) e1 e2 a
fdiv = Proxy FracExp
-> (forall (e :: * -> *). FracExp e => e a -> e a -> e a)
-> (:×:) e1 e2 a
-> (:×:) e1 e2 a
-> (:×:) e1 e2 a
forall (lang :: (* -> *) -> Constraint) (e1 :: * -> *)
       (e2 :: * -> *) (proxy :: ((* -> *) -> Constraint) -> *) a b c.
(lang e1, lang e2) =>
proxy lang
-> (forall (e :: * -> *). lang e => e a -> e b -> e c)
-> (:×:) e1 e2 a
-> (:×:) e1 e2 b
-> (:×:) e1 e2 c
liftProd2 (Proxy FracExp
forall k (t :: k). Proxy t
Proxy @FracExp) forall (e :: * -> *). FracExp e => e a -> e a -> e a
forall (e :: * -> *) a.
(FracExp e, Fractional a, Eq a) =>
e a -> e a -> e a
fdiv

instance (LogicExp e1, LogicExp e2) => LogicExp (e1 :×: e2) where
  not :: (:×:) e1 e2 Bool -> (:×:) e1 e2 Bool
not  = Proxy LogicExp
-> (forall (e :: * -> *). LogicExp e => e Bool -> e Bool)
-> (:×:) e1 e2 Bool
-> (:×:) e1 e2 Bool
forall (lang :: (* -> *) -> Constraint) (e1 :: * -> *)
       (e2 :: * -> *) (proxy :: ((* -> *) -> Constraint) -> *) a b.
(lang e1, lang e2) =>
proxy lang
-> (forall (e :: * -> *). lang e => e a -> e b)
-> (:×:) e1 e2 a
-> (:×:) e1 e2 b
liftProd  (Proxy LogicExp
forall k (t :: k). Proxy t
Proxy @LogicExp) forall (e :: * -> *). LogicExp e => e Bool -> e Bool
not
  conj :: (:×:) e1 e2 Bool -> (:×:) e1 e2 Bool -> (:×:) e1 e2 Bool
conj = Proxy LogicExp
-> (forall (e :: * -> *). LogicExp e => e Bool -> e Bool -> e Bool)
-> (:×:) e1 e2 Bool
-> (:×:) e1 e2 Bool
-> (:×:) e1 e2 Bool
forall (lang :: (* -> *) -> Constraint) (e1 :: * -> *)
       (e2 :: * -> *) (proxy :: ((* -> *) -> Constraint) -> *) a b c.
(lang e1, lang e2) =>
proxy lang
-> (forall (e :: * -> *). lang e => e a -> e b -> e c)
-> (:×:) e1 e2 a
-> (:×:) e1 e2 b
-> (:×:) e1 e2 c
liftProd2 (Proxy LogicExp
forall k (t :: k). Proxy t
Proxy @LogicExp) forall (e :: * -> *). LogicExp e => e Bool -> e Bool -> e Bool
conj
  disj :: (:×:) e1 e2 Bool -> (:×:) e1 e2 Bool -> (:×:) e1 e2 Bool
disj = Proxy LogicExp
-> (forall (e :: * -> *). LogicExp e => e Bool -> e Bool -> e Bool)
-> (:×:) e1 e2 Bool
-> (:×:) e1 e2 Bool
-> (:×:) e1 e2 Bool
forall (lang :: (* -> *) -> Constraint) (e1 :: * -> *)
       (e2 :: * -> *) (proxy :: ((* -> *) -> Constraint) -> *) a b c.
(lang e1, lang e2) =>
proxy lang
-> (forall (e :: * -> *). lang e => e a -> e b -> e c)
-> (:×:) e1 e2 a
-> (:×:) e1 e2 b
-> (:×:) e1 e2 c
liftProd2 (Proxy LogicExp
forall k (t :: k). Proxy t
Proxy @LogicExp) forall (e :: * -> *). LogicExp e => e Bool -> e Bool -> e Bool
disj
  xor :: (:×:) e1 e2 Bool -> (:×:) e1 e2 Bool -> (:×:) e1 e2 Bool
xor  = Proxy LogicExp
-> (forall (e :: * -> *). LogicExp e => e Bool -> e Bool -> e Bool)
-> (:×:) e1 e2 Bool
-> (:×:) e1 e2 Bool
-> (:×:) e1 e2 Bool
forall (lang :: (* -> *) -> Constraint) (e1 :: * -> *)
       (e2 :: * -> *) (proxy :: ((* -> *) -> Constraint) -> *) a b c.
(lang e1, lang e2) =>
proxy lang
-> (forall (e :: * -> *). lang e => e a -> e b -> e c)
-> (:×:) e1 e2 a
-> (:×:) e1 e2 b
-> (:×:) e1 e2 c
liftProd2 (Proxy LogicExp
forall k (t :: k). Proxy t
Proxy @LogicExp) forall (e :: * -> *). LogicExp e => e Bool -> e Bool -> e Bool
xor

instance (CompareExp e1, CompareExp e2) => CompareExp (e1 :×: e2) where
  eq :: (:×:) e1 e2 a -> (:×:) e1 e2 a -> (:×:) e1 e2 Bool
eq  = Proxy CompareExp
-> (forall (e :: * -> *). CompareExp e => e a -> e a -> e Bool)
-> (:×:) e1 e2 a
-> (:×:) e1 e2 a
-> (:×:) e1 e2 Bool
forall (lang :: (* -> *) -> Constraint) (e1 :: * -> *)
       (e2 :: * -> *) (proxy :: ((* -> *) -> Constraint) -> *) a b c.
(lang e1, lang e2) =>
proxy lang
-> (forall (e :: * -> *). lang e => e a -> e b -> e c)
-> (:×:) e1 e2 a
-> (:×:) e1 e2 b
-> (:×:) e1 e2 c
liftProd2 (Proxy CompareExp
forall k (t :: k). Proxy t
Proxy @CompareExp) forall (e :: * -> *). CompareExp e => e a -> e a -> e Bool
forall (e :: * -> *) a.
(CompareExp e, Eq a) =>
e a -> e a -> e Bool
eq
  neq :: (:×:) e1 e2 a -> (:×:) e1 e2 a -> (:×:) e1 e2 Bool
neq = Proxy CompareExp
-> (forall (e :: * -> *). CompareExp e => e a -> e a -> e Bool)
-> (:×:) e1 e2 a
-> (:×:) e1 e2 a
-> (:×:) e1 e2 Bool
forall (lang :: (* -> *) -> Constraint) (e1 :: * -> *)
       (e2 :: * -> *) (proxy :: ((* -> *) -> Constraint) -> *) a b c.
(lang e1, lang e2) =>
proxy lang
-> (forall (e :: * -> *). lang e => e a -> e b -> e c)
-> (:×:) e1 e2 a
-> (:×:) e1 e2 b
-> (:×:) e1 e2 c
liftProd2 (Proxy CompareExp
forall k (t :: k). Proxy t
Proxy @CompareExp) forall (e :: * -> *). CompareExp e => e a -> e a -> e Bool
forall (e :: * -> *) a.
(CompareExp e, Eq a) =>
e a -> e a -> e Bool
neq
  lt :: (:×:) e1 e2 a -> (:×:) e1 e2 a -> (:×:) e1 e2 Bool
lt  = Proxy CompareExp
-> (forall (e :: * -> *). CompareExp e => e a -> e a -> e Bool)
-> (:×:) e1 e2 a
-> (:×:) e1 e2 a
-> (:×:) e1 e2 Bool
forall (lang :: (* -> *) -> Constraint) (e1 :: * -> *)
       (e2 :: * -> *) (proxy :: ((* -> *) -> Constraint) -> *) a b c.
(lang e1, lang e2) =>
proxy lang
-> (forall (e :: * -> *). lang e => e a -> e b -> e c)
-> (:×:) e1 e2 a
-> (:×:) e1 e2 b
-> (:×:) e1 e2 c
liftProd2 (Proxy CompareExp
forall k (t :: k). Proxy t
Proxy @CompareExp) forall (e :: * -> *). CompareExp e => e a -> e a -> e Bool
forall (e :: * -> *) a.
(CompareExp e, Ord a) =>
e a -> e a -> e Bool
lt
  gt :: (:×:) e1 e2 a -> (:×:) e1 e2 a -> (:×:) e1 e2 Bool
gt  = Proxy CompareExp
-> (forall (e :: * -> *). CompareExp e => e a -> e a -> e Bool)
-> (:×:) e1 e2 a
-> (:×:) e1 e2 a
-> (:×:) e1 e2 Bool
forall (lang :: (* -> *) -> Constraint) (e1 :: * -> *)
       (e2 :: * -> *) (proxy :: ((* -> *) -> Constraint) -> *) a b c.
(lang e1, lang e2) =>
proxy lang
-> (forall (e :: * -> *). lang e => e a -> e b -> e c)
-> (:×:) e1 e2 a
-> (:×:) e1 e2 b
-> (:×:) e1 e2 c
liftProd2 (Proxy CompareExp
forall k (t :: k). Proxy t
Proxy @CompareExp) forall (e :: * -> *). CompareExp e => e a -> e a -> e Bool
forall (e :: * -> *) a.
(CompareExp e, Ord a) =>
e a -> e a -> e Bool
gt
  lte :: (:×:) e1 e2 a -> (:×:) e1 e2 a -> (:×:) e1 e2 Bool
lte = Proxy CompareExp
-> (forall (e :: * -> *). CompareExp e => e a -> e a -> e Bool)
-> (:×:) e1 e2 a
-> (:×:) e1 e2 a
-> (:×:) e1 e2 Bool
forall (lang :: (* -> *) -> Constraint) (e1 :: * -> *)
       (e2 :: * -> *) (proxy :: ((* -> *) -> Constraint) -> *) a b c.
(lang e1, lang e2) =>
proxy lang
-> (forall (e :: * -> *). lang e => e a -> e b -> e c)
-> (:×:) e1 e2 a
-> (:×:) e1 e2 b
-> (:×:) e1 e2 c
liftProd2 (Proxy CompareExp
forall k (t :: k). Proxy t
Proxy @CompareExp) forall (e :: * -> *). CompareExp e => e a -> e a -> e Bool
forall (e :: * -> *) a.
(CompareExp e, Ord a) =>
e a -> e a -> e Bool
lte
  gte :: (:×:) e1 e2 a -> (:×:) e1 e2 a -> (:×:) e1 e2 Bool
gte = Proxy CompareExp
-> (forall (e :: * -> *). CompareExp e => e a -> e a -> e Bool)
-> (:×:) e1 e2 a
-> (:×:) e1 e2 a
-> (:×:) e1 e2 Bool
forall (lang :: (* -> *) -> Constraint) (e1 :: * -> *)
       (e2 :: * -> *) (proxy :: ((* -> *) -> Constraint) -> *) a b c.
(lang e1, lang e2) =>
proxy lang
-> (forall (e :: * -> *). lang e => e a -> e b -> e c)
-> (:×:) e1 e2 a
-> (:×:) e1 e2 b
-> (:×:) e1 e2 c
liftProd2 (Proxy CompareExp
forall k (t :: k). Proxy t
Proxy @CompareExp) forall (e :: * -> *). CompareExp e => e a -> e a -> e Bool
forall (e :: * -> *) a.
(CompareExp e, Ord a) =>
e a -> e a -> e Bool
gte
  min :: (:×:) e1 e2 a -> (:×:) e1 e2 a -> (:×:) e1 e2 a
min = Proxy CompareExp
-> (forall (e :: * -> *). CompareExp e => e a -> e a -> e a)
-> (:×:) e1 e2 a
-> (:×:) e1 e2 a
-> (:×:) e1 e2 a
forall (lang :: (* -> *) -> Constraint) (e1 :: * -> *)
       (e2 :: * -> *) (proxy :: ((* -> *) -> Constraint) -> *) a b c.
(lang e1, lang e2) =>
proxy lang
-> (forall (e :: * -> *). lang e => e a -> e b -> e c)
-> (:×:) e1 e2 a
-> (:×:) e1 e2 b
-> (:×:) e1 e2 c
liftProd2 (Proxy CompareExp
forall k (t :: k). Proxy t
Proxy @CompareExp) forall (e :: * -> *). CompareExp e => e a -> e a -> e a
forall (e :: * -> *) a. (CompareExp e, Ord a) => e a -> e a -> e a
min
  max :: (:×:) e1 e2 a -> (:×:) e1 e2 a -> (:×:) e1 e2 a
max = Proxy CompareExp
-> (forall (e :: * -> *). CompareExp e => e a -> e a -> e a)
-> (:×:) e1 e2 a
-> (:×:) e1 e2 a
-> (:×:) e1 e2 a
forall (lang :: (* -> *) -> Constraint) (e1 :: * -> *)
       (e2 :: * -> *) (proxy :: ((* -> *) -> Constraint) -> *) a b c.
(lang e1, lang e2) =>
proxy lang
-> (forall (e :: * -> *). lang e => e a -> e b -> e c)
-> (:×:) e1 e2 a
-> (:×:) e1 e2 b
-> (:×:) e1 e2 c
liftProd2 (Proxy CompareExp
forall k (t :: k). Proxy t
Proxy @CompareExp) forall (e :: * -> *). CompareExp e => e a -> e a -> e a
forall (e :: * -> *) a. (CompareExp e, Ord a) => e a -> e a -> e a
max

instance (CondExpFO e1, CondExpFO e2) => CondExpFO (e1 :×: e2) where
  just :: (:×:) e1 e2 a -> (:×:) e1 e2 (Maybe a)
just = Proxy CondExpFO
-> (forall (e :: * -> *). CondExpFO e => e a -> e (Maybe a))
-> (:×:) e1 e2 a
-> (:×:) e1 e2 (Maybe a)
forall (lang :: (* -> *) -> Constraint) (e1 :: * -> *)
       (e2 :: * -> *) (proxy :: ((* -> *) -> Constraint) -> *) a b.
(lang e1, lang e2) =>
proxy lang
-> (forall (e :: * -> *). lang e => e a -> e b)
-> (:×:) e1 e2 a
-> (:×:) e1 e2 b
liftProd (Proxy CondExpFO
forall k (t :: k). Proxy t
Proxy @CondExpFO) forall (e :: * -> *). CondExpFO e => e a -> e (Maybe a)
forall (e :: * -> *) a. CondExpFO e => e a -> e (Maybe a)
just

  cases :: [(:×:) e1 e2 Bool :-> (:×:) e1 e2 a]
-> (Otherwise :-> (:×:) e1 e2 a) -> (:×:) e1 e2 a
cases [(:×:) e1 e2 Bool :-> (:×:) e1 e2 a]
cs (Otherwise
Otherwise :-> (e1 a
d1 :×: e2 a
d2)) =
    [e1 Bool :-> e1 a] -> (Otherwise :-> e1 a) -> e1 a
forall (e :: * -> *) a.
CondExpFO e =>
[e Bool :-> e a] -> (Otherwise :-> e a) -> e a
cases [e1 Bool :-> e1 a]
cs1 (Otherwise
Otherwise Otherwise -> e1 a -> Otherwise :-> e1 a
forall a b. a -> b -> a :-> b
:-> e1 a
d1) e1 a -> e2 a -> (:×:) e1 e2 a
forall (e1 :: * -> *) (e2 :: * -> *) a.
e1 a -> e2 a -> (:×:) e1 e2 a
:×: [e2 Bool :-> e2 a] -> (Otherwise :-> e2 a) -> e2 a
forall (e :: * -> *) a.
CondExpFO e =>
[e Bool :-> e a] -> (Otherwise :-> e a) -> e a
cases [e2 Bool :-> e2 a]
cs2 (Otherwise
Otherwise Otherwise -> e2 a -> Otherwise :-> e2 a
forall a b. a -> b -> a :-> b
:-> e2 a
d2)
    where
      ([e1 Bool :-> e1 a]
cs1, [e2 Bool :-> e2 a]
cs2) =
        [(e1 Bool :-> e1 a, e2 Bool :-> e2 a)]
-> ([e1 Bool :-> e1 a], [e2 Bool :-> e2 a])
forall a b. [(a, b)] -> ([a], [b])
unzip [(e1 Bool
c1 e1 Bool -> e1 a -> e1 Bool :-> e1 a
forall a b. a -> b -> a :-> b
:-> e1 a
a1, e2 Bool
c2 e2 Bool -> e2 a -> e2 Bool :-> e2 a
forall a b. a -> b -> a :-> b
:-> e2 a
a2) | ((e1 Bool
c1 :×: e2 Bool
c2) :-> (e1 a
a1 :×: e2 a
a2)) <- [(:×:) e1 e2 Bool :-> (:×:) e1 e2 a]
cs]

  partial_cases :: [(:×:) e1 e2 Bool :-> (:×:) e1 e2 a] -> (:×:) e1 e2 a
partial_cases [(:×:) e1 e2 Bool :-> (:×:) e1 e2 a]
cs = [e1 Bool :-> e1 a] -> e1 a
forall (e :: * -> *) a.
(CondExpFO e, HasCallStack) =>
[e Bool :-> e a] -> e a
partial_cases [e1 Bool :-> e1 a]
cs1 e1 a -> e2 a -> (:×:) e1 e2 a
forall (e1 :: * -> *) (e2 :: * -> *) a.
e1 a -> e2 a -> (:×:) e1 e2 a
:×: [e2 Bool :-> e2 a] -> e2 a
forall (e :: * -> *) a.
(CondExpFO e, HasCallStack) =>
[e Bool :-> e a] -> e a
partial_cases [e2 Bool :-> e2 a]
cs2
    where
      ([e1 Bool :-> e1 a]
cs1, [e2 Bool :-> e2 a]
cs2) =
        [(e1 Bool :-> e1 a, e2 Bool :-> e2 a)]
-> ([e1 Bool :-> e1 a], [e2 Bool :-> e2 a])
forall a b. [(a, b)] -> ([a], [b])
unzip [(e1 Bool
c1 e1 Bool -> e1 a -> e1 Bool :-> e1 a
forall a b. a -> b -> a :-> b
:-> e1 a
a1, e2 Bool
c2 e2 Bool -> e2 a -> e2 Bool :-> e2 a
forall a b. a -> b -> a :-> b
:-> e2 a
a2) | ((e1 Bool
c1 :×: e2 Bool
c2) :-> (e1 a
a1 :×: e2 a
a2)) <- [(:×:) e1 e2 Bool :-> (:×:) e1 e2 a]
cs]

instance (ListExpFO e1, ListExpFO e2) => ListExpFO (e1 :×: e2) where
  range :: (:×:) e1 e2 a -> (:×:) e1 e2 a -> (:×:) e1 e2 [a]
range  = Proxy ListExpFO
-> (forall (e :: * -> *). ListExpFO e => e a -> e a -> e [a])
-> (:×:) e1 e2 a
-> (:×:) e1 e2 a
-> (:×:) e1 e2 [a]
forall (lang :: (* -> *) -> Constraint) (e1 :: * -> *)
       (e2 :: * -> *) (proxy :: ((* -> *) -> Constraint) -> *) a b c.
(lang e1, lang e2) =>
proxy lang
-> (forall (e :: * -> *). lang e => e a -> e b -> e c)
-> (:×:) e1 e2 a
-> (:×:) e1 e2 b
-> (:×:) e1 e2 c
liftProd2 (Proxy ListExpFO
forall k (t :: k). Proxy t
Proxy @ListExpFO) forall (e :: * -> *). ListExpFO e => e a -> e a -> e [a]
forall (e :: * -> *) a.
(ListExpFO e, Enum a) =>
e a -> e a -> e [a]
range
  headE :: (:×:) e1 e2 [a] -> (:×:) e1 e2 (Maybe a)
headE  = Proxy ListExpFO
-> (forall (e :: * -> *). ListExpFO e => e [a] -> e (Maybe a))
-> (:×:) e1 e2 [a]
-> (:×:) e1 e2 (Maybe a)
forall (lang :: (* -> *) -> Constraint) (e1 :: * -> *)
       (e2 :: * -> *) (proxy :: ((* -> *) -> Constraint) -> *) a b.
(lang e1, lang e2) =>
proxy lang
-> (forall (e :: * -> *). lang e => e a -> e b)
-> (:×:) e1 e2 a
-> (:×:) e1 e2 b
liftProd  (Proxy ListExpFO
forall k (t :: k). Proxy t
Proxy @ListExpFO) forall (e :: * -> *). ListExpFO e => e [a] -> e (Maybe a)
forall (e :: * -> *) a. ListExpFO e => e [a] -> e (Maybe a)
headE
  append :: (:×:) e1 e2 [a] -> (:×:) e1 e2 [a] -> (:×:) e1 e2 [a]
append = Proxy ListExpFO
-> (forall (e :: * -> *). ListExpFO e => e [a] -> e [a] -> e [a])
-> (:×:) e1 e2 [a]
-> (:×:) e1 e2 [a]
-> (:×:) e1 e2 [a]
forall (lang :: (* -> *) -> Constraint) (e1 :: * -> *)
       (e2 :: * -> *) (proxy :: ((* -> *) -> Constraint) -> *) a b c.
(lang e1, lang e2) =>
proxy lang
-> (forall (e :: * -> *). lang e => e a -> e b -> e c)
-> (:×:) e1 e2 a
-> (:×:) e1 e2 b
-> (:×:) e1 e2 c
liftProd2 (Proxy ListExpFO
forall k (t :: k). Proxy t
Proxy @ListExpFO) forall (e :: * -> *). ListExpFO e => e [a] -> e [a] -> e [a]
forall (e :: * -> *) a. ListExpFO e => e [a] -> e [a] -> e [a]
append

  list :: [(:×:) e1 e2 a] -> (:×:) e1 e2 [a]
list [(:×:) e1 e2 a]
as = [e1 a] -> e1 [a]
forall (e :: * -> *) a. (ListExpFO e, DinoType a) => [e a] -> e [a]
list [e1 a]
as1 e1 [a] -> e2 [a] -> (:×:) e1 e2 [a]
forall (e1 :: * -> *) (e2 :: * -> *) a.
e1 a -> e2 a -> (:×:) e1 e2 a
:×: [e2 a] -> e2 [a]
forall (e :: * -> *) a. (ListExpFO e, DinoType a) => [e a] -> e [a]
list [e2 a]
as2
    where
      ([e1 a]
as1, [e2 a]
as2) = [(e1 a, e2 a)] -> ([e1 a], [e2 a])
forall a b. [(a, b)] -> ([a], [b])
unzip [(e1 a
a1, e2 a
a2) | (e1 a
a1 :×: e2 a
a2) <- [(:×:) e1 e2 a]
as]

instance (TupleExp e1, TupleExp e2) => TupleExp (e1 :×: e2) where
  pair :: (:×:) e1 e2 a -> (:×:) e1 e2 b -> (:×:) e1 e2 (a, b)
pair = Proxy TupleExp
-> (forall (e :: * -> *). TupleExp e => e a -> e b -> e (a, b))
-> (:×:) e1 e2 a
-> (:×:) e1 e2 b
-> (:×:) e1 e2 (a, b)
forall (lang :: (* -> *) -> Constraint) (e1 :: * -> *)
       (e2 :: * -> *) (proxy :: ((* -> *) -> Constraint) -> *) a b c.
(lang e1, lang e2) =>
proxy lang
-> (forall (e :: * -> *). lang e => e a -> e b -> e c)
-> (:×:) e1 e2 a
-> (:×:) e1 e2 b
-> (:×:) e1 e2 c
liftProd2 (Proxy TupleExp
forall k (t :: k). Proxy t
Proxy @TupleExp) forall (e :: * -> *). TupleExp e => e a -> e b -> e (a, b)
forall (e :: * -> *) a b. TupleExp e => e a -> e b -> e (a, b)
pair
  fstE :: (:×:) e1 e2 (a, b) -> (:×:) e1 e2 a
fstE = Proxy TupleExp
-> (forall (e :: * -> *). TupleExp e => e (a, b) -> e a)
-> (:×:) e1 e2 (a, b)
-> (:×:) e1 e2 a
forall (lang :: (* -> *) -> Constraint) (e1 :: * -> *)
       (e2 :: * -> *) (proxy :: ((* -> *) -> Constraint) -> *) a b.
(lang e1, lang e2) =>
proxy lang
-> (forall (e :: * -> *). lang e => e a -> e b)
-> (:×:) e1 e2 a
-> (:×:) e1 e2 b
liftProd  (Proxy TupleExp
forall k (t :: k). Proxy t
Proxy @TupleExp) forall (e :: * -> *). TupleExp e => e (a, b) -> e a
forall (e :: * -> *) a b. TupleExp e => e (a, b) -> e a
fstE
  sndE :: (:×:) e1 e2 (a, b) -> (:×:) e1 e2 b
sndE = Proxy TupleExp
-> (forall (e :: * -> *). TupleExp e => e (a, b) -> e b)
-> (:×:) e1 e2 (a, b)
-> (:×:) e1 e2 b
forall (lang :: (* -> *) -> Constraint) (e1 :: * -> *)
       (e2 :: * -> *) (proxy :: ((* -> *) -> Constraint) -> *) a b.
(lang e1, lang e2) =>
proxy lang
-> (forall (e :: * -> *). lang e => e a -> e b)
-> (:×:) e1 e2 a
-> (:×:) e1 e2 b
liftProd  (Proxy TupleExp
forall k (t :: k). Proxy t
Proxy @TupleExp) forall (e :: * -> *). TupleExp e => e (a, b) -> e b
forall (e :: * -> *) a b. TupleExp e => e (a, b) -> e b
sndE

instance (FieldExp e1, FieldExp e2) => FieldExp (e1 :×: e2) where
  getField :: proxy f -> (:×:) e1 e2 r -> (:×:) e1 e2 a
getField proxy f
f = Proxy FieldExp
-> (forall (e :: * -> *). FieldExp e => e r -> e a)
-> (:×:) e1 e2 r
-> (:×:) e1 e2 a
forall (lang :: (* -> *) -> Constraint) (e1 :: * -> *)
       (e2 :: * -> *) (proxy :: ((* -> *) -> Constraint) -> *) a b.
(lang e1, lang e2) =>
proxy lang
-> (forall (e :: * -> *). lang e => e a -> e b)
-> (:×:) e1 e2 a
-> (:×:) e1 e2 b
liftProd (Proxy FieldExp
forall k (t :: k). Proxy t
Proxy @FieldExp) (proxy f -> e r -> e a
forall (e :: * -> *) (f :: Symbol) r a (proxy :: Symbol -> *).
(FieldExp e, KnownSymbol f, HasField f r a, DinoType a) =>
proxy f -> e r -> e a
getField proxy f
f)

instance (AnnExp ann e1, AnnExp ann e2) => AnnExp ann (e1 :×: e2) where
  ann :: ann -> (:×:) e1 e2 a -> (:×:) e1 e2 a
ann ann
a = Proxy (AnnExp ann)
-> (forall (e :: * -> *). AnnExp ann e => e a -> e a)
-> (:×:) e1 e2 a
-> (:×:) e1 e2 a
forall (lang :: (* -> *) -> Constraint) (e1 :: * -> *)
       (e2 :: * -> *) (proxy :: ((* -> *) -> Constraint) -> *) a b.
(lang e1, lang e2) =>
proxy lang
-> (forall (e :: * -> *). lang e => e a -> e b)
-> (:×:) e1 e2 a
-> (:×:) e1 e2 b
liftProd (Proxy (AnnExp ann)
forall k (t :: k). Proxy t
Proxy @(AnnExp ann)) (ann -> e a -> e a
forall k ann (e :: k -> *) (a :: k).
AnnExp ann e =>
ann -> e a -> e a
ann ann
a)

instance (AssertExp e1, AssertExp e2) => AssertExp (e1 :×: e2) where
  assert :: Text -> (:×:) e1 e2 Bool -> (:×:) e1 e2 a -> (:×:) e1 e2 a
assert   Text
lab = Proxy AssertExp
-> (forall (e :: * -> *). AssertExp e => e Bool -> e a -> e a)
-> (:×:) e1 e2 Bool
-> (:×:) e1 e2 a
-> (:×:) e1 e2 a
forall (lang :: (* -> *) -> Constraint) (e1 :: * -> *)
       (e2 :: * -> *) (proxy :: ((* -> *) -> Constraint) -> *) a b c.
(lang e1, lang e2) =>
proxy lang
-> (forall (e :: * -> *). lang e => e a -> e b -> e c)
-> (:×:) e1 e2 a
-> (:×:) e1 e2 b
-> (:×:) e1 e2 c
liftProd2 (Proxy AssertExp
forall k (t :: k). Proxy t
Proxy @AssertExp) (Text -> e Bool -> e a -> e a
forall (e :: * -> *) a. AssertExp e => Text -> e Bool -> e a -> e a
assert Text
lab)
  assertEq :: Text -> (:×:) e1 e2 a -> (:×:) e1 e2 a -> (:×:) e1 e2 a
assertEq Text
lab = Proxy AssertExp
-> (forall (e :: * -> *). AssertExp e => e a -> e a -> e a)
-> (:×:) e1 e2 a
-> (:×:) e1 e2 a
-> (:×:) e1 e2 a
forall (lang :: (* -> *) -> Constraint) (e1 :: * -> *)
       (e2 :: * -> *) (proxy :: ((* -> *) -> Constraint) -> *) a b c.
(lang e1, lang e2) =>
proxy lang
-> (forall (e :: * -> *). lang e => e a -> e b -> e c)
-> (:×:) e1 e2 a
-> (:×:) e1 e2 b
-> (:×:) e1 e2 c
liftProd2 (Proxy AssertExp
forall k (t :: k). Proxy t
Proxy @AssertExp) (Text -> e a -> e a -> e a
forall (e :: * -> *) a.
(AssertExp e, Eq a, Show a) =>
Text -> e a -> e a -> e a
assertEq Text
lab)

instance (VarExp e1, VarExp e2) => VarExp (e1 :×: e2) where
  varE :: Text -> (:×:) e1 e2 a
varE Text
v = Proxy VarExp
-> (forall (e :: * -> *). VarExp e => e a) -> (:×:) e1 e2 a
forall (lang :: (* -> *) -> Constraint) (e1 :: * -> *)
       (e2 :: * -> *) (proxy :: ((* -> *) -> Constraint) -> *) a.
(lang e1, lang e2) =>
proxy lang
-> (forall (e :: * -> *). lang e => e a) -> (:×:) e1 e2 a
mkProd (Proxy VarExp
forall k (t :: k). Proxy t
Proxy @VarExp) (Text -> e a
forall (e :: * -> *) a. (VarExp e, DinoType a) => Text -> e a
varE Text
v)

instance (CondIntensional e1, CondIntensional e2) =>
         CondIntensional (e1 :×: e2) where
  maybeI :: Text
-> (:×:) e1 e2 b
-> (:×:) e1 e2 b
-> (:×:) e1 e2 (Maybe a)
-> (:×:) e1 e2 b
maybeI Text
v = Proxy CondIntensional
-> (forall (e :: * -> *).
    CondIntensional e =>
    e b -> e b -> e (Maybe a) -> e b)
-> (:×:) e1 e2 b
-> (:×:) e1 e2 b
-> (:×:) e1 e2 (Maybe a)
-> (:×:) e1 e2 b
forall (lang :: (* -> *) -> Constraint) (e1 :: * -> *)
       (e2 :: * -> *) (proxy :: ((* -> *) -> Constraint) -> *) a b c d.
(lang e1, lang e2) =>
proxy lang
-> (forall (e :: * -> *). lang e => e a -> e b -> e c -> e d)
-> (:×:) e1 e2 a
-> (:×:) e1 e2 b
-> (:×:) e1 e2 c
-> (:×:) e1 e2 d
liftProd3 (Proxy CondIntensional
forall k (t :: k). Proxy t
Proxy @CondIntensional) (Text -> e b -> e b -> e (Maybe a) -> e b
forall (e :: * -> *) a b.
(CondIntensional e, DinoType a) =>
Text -> e b -> e b -> e (Maybe a) -> e b
maybeI Text
v)

instance (ListIntensional e1, ListIntensional e2) =>
         ListIntensional (e1 :×: e2) where
  mapI :: Text -> (:×:) e1 e2 b -> (:×:) e1 e2 [a] -> (:×:) e1 e2 [b]
mapI Text
v       = Proxy ListIntensional
-> (forall (e :: * -> *).
    ListIntensional e =>
    e b -> e [a] -> e [b])
-> (:×:) e1 e2 b
-> (:×:) e1 e2 [a]
-> (:×:) e1 e2 [b]
forall (lang :: (* -> *) -> Constraint) (e1 :: * -> *)
       (e2 :: * -> *) (proxy :: ((* -> *) -> Constraint) -> *) a b c.
(lang e1, lang e2) =>
proxy lang
-> (forall (e :: * -> *). lang e => e a -> e b -> e c)
-> (:×:) e1 e2 a
-> (:×:) e1 e2 b
-> (:×:) e1 e2 c
liftProd2 (Proxy ListIntensional
forall k (t :: k). Proxy t
Proxy @ListIntensional) (Text -> e b -> e [a] -> e [b]
forall (e :: * -> *) a b.
(ListIntensional e, DinoType a) =>
Text -> e b -> e [a] -> e [b]
mapI Text
v)
  dropWhileI :: Text -> (:×:) e1 e2 Bool -> (:×:) e1 e2 [a] -> (:×:) e1 e2 [a]
dropWhileI Text
v = Proxy ListIntensional
-> (forall (e :: * -> *).
    ListIntensional e =>
    e Bool -> e [a] -> e [a])
-> (:×:) e1 e2 Bool
-> (:×:) e1 e2 [a]
-> (:×:) e1 e2 [a]
forall (lang :: (* -> *) -> Constraint) (e1 :: * -> *)
       (e2 :: * -> *) (proxy :: ((* -> *) -> Constraint) -> *) a b c.
(lang e1, lang e2) =>
proxy lang
-> (forall (e :: * -> *). lang e => e a -> e b -> e c)
-> (:×:) e1 e2 a
-> (:×:) e1 e2 b
-> (:×:) e1 e2 c
liftProd2 (Proxy ListIntensional
forall k (t :: k). Proxy t
Proxy @ListIntensional) (Text -> e Bool -> e [a] -> e [a]
forall (e :: * -> *) a.
(ListIntensional e, DinoType a) =>
Text -> e Bool -> e [a] -> e [a]
dropWhileI Text
v)
  foldI :: Text
-> Text
-> (:×:) e1 e2 a
-> (:×:) e1 e2 a
-> (:×:) e1 e2 [b]
-> (:×:) e1 e2 a
foldI Text
va Text
vb  = Proxy ListIntensional
-> (forall (e :: * -> *).
    ListIntensional e =>
    e a -> e a -> e [b] -> e a)
-> (:×:) e1 e2 a
-> (:×:) e1 e2 a
-> (:×:) e1 e2 [b]
-> (:×:) e1 e2 a
forall (lang :: (* -> *) -> Constraint) (e1 :: * -> *)
       (e2 :: * -> *) (proxy :: ((* -> *) -> Constraint) -> *) a b c d.
(lang e1, lang e2) =>
proxy lang
-> (forall (e :: * -> *). lang e => e a -> e b -> e c -> e d)
-> (:×:) e1 e2 a
-> (:×:) e1 e2 b
-> (:×:) e1 e2 c
-> (:×:) e1 e2 d
liftProd3 (Proxy ListIntensional
forall k (t :: k). Proxy t
Proxy @ListIntensional) (Text -> Text -> e a -> e a -> e [b] -> e a
forall (e :: * -> *) a b.
(ListIntensional e, DinoType a, DinoType b) =>
Text -> Text -> e a -> e a -> e [b] -> e a
foldI Text
va Text
vb)

instance (LetIntensional e1, LetIntensional e2) =>
         LetIntensional (e1 :×: e2) where
  letI :: Text -> (:×:) e1 e2 a -> (:×:) e1 e2 b -> (:×:) e1 e2 b
letI Text
v = Proxy LetIntensional
-> (forall (e :: * -> *). LetIntensional e => e a -> e b -> e b)
-> (:×:) e1 e2 a
-> (:×:) e1 e2 b
-> (:×:) e1 e2 b
forall (lang :: (* -> *) -> Constraint) (e1 :: * -> *)
       (e2 :: * -> *) (proxy :: ((* -> *) -> Constraint) -> *) a b c.
(lang e1, lang e2) =>
proxy lang
-> (forall (e :: * -> *). lang e => e a -> e b -> e c)
-> (:×:) e1 e2 a
-> (:×:) e1 e2 b
-> (:×:) e1 e2 c
liftProd2 (Proxy LetIntensional
forall k (t :: k). Proxy t
Proxy @LetIntensional) (Text -> e a -> e b -> e b
forall (e :: * -> *) a b.
(LetIntensional e, DinoType a) =>
Text -> e a -> e b -> e b
letI Text
v)



--------------------------------------------------------------------------------
-- * Intensional interpretation
--------------------------------------------------------------------------------

-- Intensional interpretation essentially means to analyze the expression
-- syntactically rather than evaluating it.
--
-- <https://en.wikipedia.org/wiki/Extensional_and_intensional_definitions>



-- | Representation of the set of variables used by bindings in an expression.
-- An entry @(v, n)@ means that the base name @v@ is used possibly appended with
-- a number that is at most @n@.
--
-- Since the keys represent variable base names, they are not allowed to end
-- with digits.
type BindSet = HashMap Text Int

-- | Return an unused variable name from the given base name
--
-- The returned 'BindSet' includes the new variable.
freshVar :: Text -> BindSet -> (Text, BindSet)
freshVar :: Text -> BindSet -> (Text, BindSet)
freshVar Text
v BindSet
bs = case Text -> BindSet -> Maybe Int
forall k v. (Eq k, Hashable k) => k -> HashMap k v -> Maybe v
HashMap.lookup Text
v BindSet
bs of
  Maybe Int
Nothing -> (Text
v, Text -> Int -> BindSet -> BindSet
forall k v.
(Eq k, Hashable k) =>
k -> v -> HashMap k v -> HashMap k v
HashMap.insert Text
v Int
0 BindSet
bs)
  Just Int
n  -> (Text
v Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> String -> Text
forall a. IsString a => String -> a
fromString (Int -> String
forall a. Show a => a -> String
show Int
n), Text -> Int -> BindSet -> BindSet
forall k v.
(Eq k, Hashable k) =>
k -> v -> HashMap k v -> HashMap k v
HashMap.insert Text
v (Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1) BindSet
bs)

-- | Allow intensional interpretation of higher-order constructs
--
-- 'Intensional' is used to obtain instances of HOS classes from their
-- intensional counterparts. For example, given
-- @(`CondExpFO` e, `VarExp` e, `CondIntensional` e)@, we get
-- @`CondExp` (`Intensional` e)@.
--
-- Pairing the interpretation with a 'BindSet' allows generating symbolic
-- variables to inspect higher-order constructs rather than just running them.
newtype Intensional e a = Intensional
  { Intensional e a -> (:×:) (Fold BindSet) e a
unIntensional :: (Fold BindSet :×: e) a
  } deriving ( a -> Intensional e a
(forall a. DinoType a => a -> Intensional e a)
-> ConstExp (Intensional e)
forall a. DinoType a => a -> Intensional e a
forall (e :: * -> *) a.
(ConstExp e, DinoType a) =>
a -> Intensional e a
forall (e :: * -> *).
(forall a. DinoType a => a -> e a) -> ConstExp e
lit :: a -> Intensional e a
$clit :: forall (e :: * -> *) a.
(ConstExp e, DinoType a) =>
a -> Intensional e a
ConstExp
             , Int -> Intensional e a -> Intensional e a
Intensional e a -> Intensional e a -> Intensional e a
Intensional e a -> Intensional e a -> Intensional e a
Intensional e a -> Intensional e a -> Intensional e a
Intensional e a -> Intensional e a
Intensional e a -> Intensional e a
Intensional e a -> Intensional e b
Intensional e a -> Intensional e b
Intensional e a -> Intensional e b
(forall a.
 Num a =>
 Intensional e a -> Intensional e a -> Intensional e a)
-> (forall a.
    Num a =>
    Intensional e a -> Intensional e a -> Intensional e a)
-> (forall a.
    Num a =>
    Intensional e a -> Intensional e a -> Intensional e a)
-> (forall a. Num a => Intensional e a -> Intensional e a)
-> (forall a. Num a => Intensional e a -> Intensional e a)
-> (forall a b.
    (Integral a, DinoType b, Num b) =>
    Intensional e a -> Intensional e b)
-> (forall a b.
    (RealFrac a, DinoType b, Integral b) =>
    Intensional e a -> Intensional e b)
-> (forall a b.
    (RealFrac a, DinoType b, Integral b) =>
    Intensional e a -> Intensional e b)
-> (forall a.
    RealFrac a =>
    Int -> Intensional e a -> Intensional e a)
-> NumExp (Intensional e)
forall a. Num a => Intensional e a -> Intensional e a
forall a.
Num a =>
Intensional e a -> Intensional e a -> Intensional e a
forall a. RealFrac a => Int -> Intensional e a -> Intensional e a
forall a b.
(Integral a, DinoType b, Num b) =>
Intensional e a -> Intensional e b
forall a b.
(RealFrac a, DinoType b, Integral b) =>
Intensional e a -> Intensional e b
forall (e :: * -> *) a.
(NumExp e, Num a) =>
Intensional e a -> Intensional e a
forall (e :: * -> *) a.
(NumExp e, Num a) =>
Intensional e a -> Intensional e a -> Intensional e a
forall (e :: * -> *) a.
(NumExp e, RealFrac a) =>
Int -> Intensional e a -> Intensional e a
forall (e :: * -> *) a b.
(NumExp e, Integral a, DinoType b, Num b) =>
Intensional e a -> Intensional e b
forall (e :: * -> *) a b.
(NumExp e, RealFrac a, DinoType b, Integral b) =>
Intensional e a -> Intensional e b
forall (e :: * -> *).
(forall a. Num a => e a -> e a -> e a)
-> (forall a. Num a => e a -> e a -> e a)
-> (forall a. Num a => e a -> e a -> e a)
-> (forall a. Num a => e a -> e a)
-> (forall a. Num a => e a -> e a)
-> (forall a b. (Integral a, DinoType b, Num b) => e a -> e b)
-> (forall a b. (RealFrac a, DinoType b, Integral b) => e a -> e b)
-> (forall a b. (RealFrac a, DinoType b, Integral b) => e a -> e b)
-> (forall a. RealFrac a => Int -> e a -> e a)
-> NumExp e
roundN :: Int -> Intensional e a -> Intensional e a
$croundN :: forall (e :: * -> *) a.
(NumExp e, RealFrac a) =>
Int -> Intensional e a -> Intensional e a
truncate :: Intensional e a -> Intensional e b
$ctruncate :: forall (e :: * -> *) a b.
(NumExp e, RealFrac a, DinoType b, Integral b) =>
Intensional e a -> Intensional e b
floor :: Intensional e a -> Intensional e b
$cfloor :: forall (e :: * -> *) a b.
(NumExp e, RealFrac a, DinoType b, Integral b) =>
Intensional e a -> Intensional e b
fromIntegral :: Intensional e a -> Intensional e b
$cfromIntegral :: forall (e :: * -> *) a b.
(NumExp e, Integral a, DinoType b, Num b) =>
Intensional e a -> Intensional e b
signE :: Intensional e a -> Intensional e a
$csignE :: forall (e :: * -> *) a.
(NumExp e, Num a) =>
Intensional e a -> Intensional e a
absE :: Intensional e a -> Intensional e a
$cabsE :: forall (e :: * -> *) a.
(NumExp e, Num a) =>
Intensional e a -> Intensional e a
mul :: Intensional e a -> Intensional e a -> Intensional e a
$cmul :: forall (e :: * -> *) a.
(NumExp e, Num a) =>
Intensional e a -> Intensional e a -> Intensional e a
sub :: Intensional e a -> Intensional e a -> Intensional e a
$csub :: forall (e :: * -> *) a.
(NumExp e, Num a) =>
Intensional e a -> Intensional e a -> Intensional e a
add :: Intensional e a -> Intensional e a -> Intensional e a
$cadd :: forall (e :: * -> *) a.
(NumExp e, Num a) =>
Intensional e a -> Intensional e a -> Intensional e a
NumExp
             , Intensional e a -> Intensional e a -> Intensional e a
(forall a.
 (Fractional a, Eq a) =>
 Intensional e a -> Intensional e a -> Intensional e a)
-> FracExp (Intensional e)
forall a.
(Fractional a, Eq a) =>
Intensional e a -> Intensional e a -> Intensional e a
forall (e :: * -> *) a.
(FracExp e, Fractional a, Eq a) =>
Intensional e a -> Intensional e a -> Intensional e a
forall (e :: * -> *).
(forall a. (Fractional a, Eq a) => e a -> e a -> e a) -> FracExp e
fdiv :: Intensional e a -> Intensional e a -> Intensional e a
$cfdiv :: forall (e :: * -> *) a.
(FracExp e, Fractional a, Eq a) =>
Intensional e a -> Intensional e a -> Intensional e a
FracExp
             , Intensional e Bool -> Intensional e Bool
Intensional e Bool -> Intensional e Bool -> Intensional e Bool
(Intensional e Bool -> Intensional e Bool)
-> (Intensional e Bool -> Intensional e Bool -> Intensional e Bool)
-> (Intensional e Bool -> Intensional e Bool -> Intensional e Bool)
-> (Intensional e Bool -> Intensional e Bool -> Intensional e Bool)
-> LogicExp (Intensional e)
forall (e :: * -> *).
LogicExp e =>
Intensional e Bool -> Intensional e Bool
forall (e :: * -> *).
LogicExp e =>
Intensional e Bool -> Intensional e Bool -> Intensional e Bool
forall (e :: * -> *).
(e Bool -> e Bool)
-> (e Bool -> e Bool -> e Bool)
-> (e Bool -> e Bool -> e Bool)
-> (e Bool -> e Bool -> e Bool)
-> LogicExp e
xor :: Intensional e Bool -> Intensional e Bool -> Intensional e Bool
$cxor :: forall (e :: * -> *).
LogicExp e =>
Intensional e Bool -> Intensional e Bool -> Intensional e Bool
disj :: Intensional e Bool -> Intensional e Bool -> Intensional e Bool
$cdisj :: forall (e :: * -> *).
LogicExp e =>
Intensional e Bool -> Intensional e Bool -> Intensional e Bool
conj :: Intensional e Bool -> Intensional e Bool -> Intensional e Bool
$cconj :: forall (e :: * -> *).
LogicExp e =>
Intensional e Bool -> Intensional e Bool -> Intensional e Bool
not :: Intensional e Bool -> Intensional e Bool
$cnot :: forall (e :: * -> *).
LogicExp e =>
Intensional e Bool -> Intensional e Bool
LogicExp
             , Intensional e a -> Intensional e a -> Intensional e Bool
Intensional e a -> Intensional e a -> Intensional e Bool
Intensional e a -> Intensional e a -> Intensional e Bool
Intensional e a -> Intensional e a -> Intensional e Bool
Intensional e a -> Intensional e a -> Intensional e Bool
Intensional e a -> Intensional e a -> Intensional e Bool
Intensional e a -> Intensional e a -> Intensional e a
Intensional e a -> Intensional e a -> Intensional e a
(forall a.
 Eq a =>
 Intensional e a -> Intensional e a -> Intensional e Bool)
-> (forall a.
    Eq a =>
    Intensional e a -> Intensional e a -> Intensional e Bool)
-> (forall a.
    Ord a =>
    Intensional e a -> Intensional e a -> Intensional e Bool)
-> (forall a.
    Ord a =>
    Intensional e a -> Intensional e a -> Intensional e Bool)
-> (forall a.
    Ord a =>
    Intensional e a -> Intensional e a -> Intensional e Bool)
-> (forall a.
    Ord a =>
    Intensional e a -> Intensional e a -> Intensional e Bool)
-> (forall a.
    Ord a =>
    Intensional e a -> Intensional e a -> Intensional e a)
-> (forall a.
    Ord a =>
    Intensional e a -> Intensional e a -> Intensional e a)
-> CompareExp (Intensional e)
forall a.
Eq a =>
Intensional e a -> Intensional e a -> Intensional e Bool
forall a.
Ord a =>
Intensional e a -> Intensional e a -> Intensional e a
forall a.
Ord a =>
Intensional e a -> Intensional e a -> Intensional e Bool
forall (e :: * -> *) a.
(CompareExp e, Eq a) =>
Intensional e a -> Intensional e a -> Intensional e Bool
forall (e :: * -> *) a.
(CompareExp e, Ord a) =>
Intensional e a -> Intensional e a -> Intensional e a
forall (e :: * -> *) a.
(CompareExp e, Ord a) =>
Intensional e a -> Intensional e a -> Intensional e Bool
forall (e :: * -> *).
(forall a. Eq a => e a -> e a -> e Bool)
-> (forall a. Eq a => e a -> e a -> e Bool)
-> (forall a. Ord a => e a -> e a -> e Bool)
-> (forall a. Ord a => e a -> e a -> e Bool)
-> (forall a. Ord a => e a -> e a -> e Bool)
-> (forall a. Ord a => e a -> e a -> e Bool)
-> (forall a. Ord a => e a -> e a -> e a)
-> (forall a. Ord a => e a -> e a -> e a)
-> CompareExp e
max :: Intensional e a -> Intensional e a -> Intensional e a
$cmax :: forall (e :: * -> *) a.
(CompareExp e, Ord a) =>
Intensional e a -> Intensional e a -> Intensional e a
min :: Intensional e a -> Intensional e a -> Intensional e a
$cmin :: forall (e :: * -> *) a.
(CompareExp e, Ord a) =>
Intensional e a -> Intensional e a -> Intensional e a
gte :: Intensional e a -> Intensional e a -> Intensional e Bool
$cgte :: forall (e :: * -> *) a.
(CompareExp e, Ord a) =>
Intensional e a -> Intensional e a -> Intensional e Bool
lte :: Intensional e a -> Intensional e a -> Intensional e Bool
$clte :: forall (e :: * -> *) a.
(CompareExp e, Ord a) =>
Intensional e a -> Intensional e a -> Intensional e Bool
gt :: Intensional e a -> Intensional e a -> Intensional e Bool
$cgt :: forall (e :: * -> *) a.
(CompareExp e, Ord a) =>
Intensional e a -> Intensional e a -> Intensional e Bool
lt :: Intensional e a -> Intensional e a -> Intensional e Bool
$clt :: forall (e :: * -> *) a.
(CompareExp e, Ord a) =>
Intensional e a -> Intensional e a -> Intensional e Bool
neq :: Intensional e a -> Intensional e a -> Intensional e Bool
$cneq :: forall (e :: * -> *) a.
(CompareExp e, Eq a) =>
Intensional e a -> Intensional e a -> Intensional e Bool
eq :: Intensional e a -> Intensional e a -> Intensional e Bool
$ceq :: forall (e :: * -> *) a.
(CompareExp e, Eq a) =>
Intensional e a -> Intensional e a -> Intensional e Bool
CompareExp
             , [Intensional e Bool :-> Intensional e a]
-> (Otherwise :-> Intensional e a) -> Intensional e a
[Intensional e Bool :-> Intensional e a] -> Intensional e a
Intensional e a -> Intensional e (Maybe a)
(forall a. Intensional e a -> Intensional e (Maybe a))
-> (forall a.
    [Intensional e Bool :-> Intensional e a]
    -> (Otherwise :-> Intensional e a) -> Intensional e a)
-> (forall a.
    HasCallStack =>
    [Intensional e Bool :-> Intensional e a] -> Intensional e a)
-> CondExpFO (Intensional e)
forall a.
HasCallStack =>
[Intensional e Bool :-> Intensional e a] -> Intensional e a
forall a.
[Intensional e Bool :-> Intensional e a]
-> (Otherwise :-> Intensional e a) -> Intensional e a
forall a. Intensional e a -> Intensional e (Maybe a)
forall (e :: * -> *) a.
(CondExpFO e, HasCallStack) =>
[Intensional e Bool :-> Intensional e a] -> Intensional e a
forall (e :: * -> *) a.
CondExpFO e =>
[Intensional e Bool :-> Intensional e a]
-> (Otherwise :-> Intensional e a) -> Intensional e a
forall (e :: * -> *) a.
CondExpFO e =>
Intensional e a -> Intensional e (Maybe a)
forall (e :: * -> *).
(forall a. e a -> e (Maybe a))
-> (forall a. [e Bool :-> e a] -> (Otherwise :-> e a) -> e a)
-> (forall a. HasCallStack => [e Bool :-> e a] -> e a)
-> CondExpFO e
partial_cases :: [Intensional e Bool :-> Intensional e a] -> Intensional e a
$cpartial_cases :: forall (e :: * -> *) a.
(CondExpFO e, HasCallStack) =>
[Intensional e Bool :-> Intensional e a] -> Intensional e a
cases :: [Intensional e Bool :-> Intensional e a]
-> (Otherwise :-> Intensional e a) -> Intensional e a
$ccases :: forall (e :: * -> *) a.
CondExpFO e =>
[Intensional e Bool :-> Intensional e a]
-> (Otherwise :-> Intensional e a) -> Intensional e a
just :: Intensional e a -> Intensional e (Maybe a)
$cjust :: forall (e :: * -> *) a.
CondExpFO e =>
Intensional e a -> Intensional e (Maybe a)
CondExpFO
             , [Intensional e a] -> Intensional e [a]
Intensional e a -> Intensional e a -> Intensional e [a]
Intensional e [a] -> Intensional e (Maybe a)
Intensional e [a] -> Intensional e [a] -> Intensional e [a]
(forall a.
 Enum a =>
 Intensional e a -> Intensional e a -> Intensional e [a])
-> (forall a. DinoType a => [Intensional e a] -> Intensional e [a])
-> (forall a. Intensional e [a] -> Intensional e (Maybe a))
-> (forall a.
    Intensional e [a] -> Intensional e [a] -> Intensional e [a])
-> ListExpFO (Intensional e)
forall a.
Enum a =>
Intensional e a -> Intensional e a -> Intensional e [a]
forall a. DinoType a => [Intensional e a] -> Intensional e [a]
forall a. Intensional e [a] -> Intensional e (Maybe a)
forall a.
Intensional e [a] -> Intensional e [a] -> Intensional e [a]
forall (e :: * -> *) a.
(ListExpFO e, Enum a) =>
Intensional e a -> Intensional e a -> Intensional e [a]
forall (e :: * -> *) a.
(ListExpFO e, DinoType a) =>
[Intensional e a] -> Intensional e [a]
forall (e :: * -> *) a.
ListExpFO e =>
Intensional e [a] -> Intensional e (Maybe a)
forall (e :: * -> *) a.
ListExpFO e =>
Intensional e [a] -> Intensional e [a] -> Intensional e [a]
forall (e :: * -> *).
(forall a. Enum a => e a -> e a -> e [a])
-> (forall a. DinoType a => [e a] -> e [a])
-> (forall a. e [a] -> e (Maybe a))
-> (forall a. e [a] -> e [a] -> e [a])
-> ListExpFO e
append :: Intensional e [a] -> Intensional e [a] -> Intensional e [a]
$cappend :: forall (e :: * -> *) a.
ListExpFO e =>
Intensional e [a] -> Intensional e [a] -> Intensional e [a]
headE :: Intensional e [a] -> Intensional e (Maybe a)
$cheadE :: forall (e :: * -> *) a.
ListExpFO e =>
Intensional e [a] -> Intensional e (Maybe a)
list :: [Intensional e a] -> Intensional e [a]
$clist :: forall (e :: * -> *) a.
(ListExpFO e, DinoType a) =>
[Intensional e a] -> Intensional e [a]
range :: Intensional e a -> Intensional e a -> Intensional e [a]
$crange :: forall (e :: * -> *) a.
(ListExpFO e, Enum a) =>
Intensional e a -> Intensional e a -> Intensional e [a]
ListExpFO
             , Intensional e a -> Intensional e b -> Intensional e (a, b)
Intensional e (a, b) -> Intensional e a
Intensional e (a, b) -> Intensional e b
(forall a b.
 Intensional e a -> Intensional e b -> Intensional e (a, b))
-> (forall a b. Intensional e (a, b) -> Intensional e a)
-> (forall a b. Intensional e (a, b) -> Intensional e b)
-> TupleExp (Intensional e)
forall a b.
Intensional e a -> Intensional e b -> Intensional e (a, b)
forall a b. Intensional e (a, b) -> Intensional e a
forall a b. Intensional e (a, b) -> Intensional e b
forall (e :: * -> *) a b.
TupleExp e =>
Intensional e a -> Intensional e b -> Intensional e (a, b)
forall (e :: * -> *) a b.
TupleExp e =>
Intensional e (a, b) -> Intensional e a
forall (e :: * -> *) a b.
TupleExp e =>
Intensional e (a, b) -> Intensional e b
forall (e :: * -> *).
(forall a b. e a -> e b -> e (a, b))
-> (forall a b. e (a, b) -> e a)
-> (forall a b. e (a, b) -> e b)
-> TupleExp e
sndE :: Intensional e (a, b) -> Intensional e b
$csndE :: forall (e :: * -> *) a b.
TupleExp e =>
Intensional e (a, b) -> Intensional e b
fstE :: Intensional e (a, b) -> Intensional e a
$cfstE :: forall (e :: * -> *) a b.
TupleExp e =>
Intensional e (a, b) -> Intensional e a
pair :: Intensional e a -> Intensional e b -> Intensional e (a, b)
$cpair :: forall (e :: * -> *) a b.
TupleExp e =>
Intensional e a -> Intensional e b -> Intensional e (a, b)
TupleExp
             , proxy f -> Intensional e r -> Intensional e a
(forall (f :: Symbol) r a (proxy :: Symbol -> *).
 (KnownSymbol f, HasField f r a, DinoType a) =>
 proxy f -> Intensional e r -> Intensional e a)
-> FieldExp (Intensional e)
forall (f :: Symbol) r a (proxy :: Symbol -> *).
(KnownSymbol f, HasField f r a, DinoType a) =>
proxy f -> Intensional e r -> Intensional e a
forall (e :: * -> *) (f :: Symbol) r a (proxy :: Symbol -> *).
(FieldExp e, KnownSymbol f, HasField f r a, DinoType a) =>
proxy f -> Intensional e r -> Intensional e a
forall (e :: * -> *).
(forall (f :: Symbol) r a (proxy :: Symbol -> *).
 (KnownSymbol f, HasField f r a, DinoType a) =>
 proxy f -> e r -> e a)
-> FieldExp e
getField :: proxy f -> Intensional e r -> Intensional e a
$cgetField :: forall (e :: * -> *) (f :: Symbol) r a (proxy :: Symbol -> *).
(FieldExp e, KnownSymbol f, HasField f r a, DinoType a) =>
proxy f -> Intensional e r -> Intensional e a
FieldExp
             , AnnExp ann
             , Text -> Intensional e a -> Intensional e a -> Intensional e a
Text -> Intensional e Bool -> Intensional e a -> Intensional e a
(forall a.
 Text -> Intensional e Bool -> Intensional e a -> Intensional e a)
-> (forall a.
    (Eq a, Show a) =>
    Text -> Intensional e a -> Intensional e a -> Intensional e a)
-> AssertExp (Intensional e)
forall a.
(Eq a, Show a) =>
Text -> Intensional e a -> Intensional e a -> Intensional e a
forall a.
Text -> Intensional e Bool -> Intensional e a -> Intensional e a
forall (e :: * -> *) a.
(AssertExp e, Eq a, Show a) =>
Text -> Intensional e a -> Intensional e a -> Intensional e a
forall (e :: * -> *) a.
AssertExp e =>
Text -> Intensional e Bool -> Intensional e a -> Intensional e a
forall (e :: * -> *).
(forall a. Text -> e Bool -> e a -> e a)
-> (forall a. (Eq a, Show a) => Text -> e a -> e a -> e a)
-> AssertExp e
assertEq :: Text -> Intensional e a -> Intensional e a -> Intensional e a
$cassertEq :: forall (e :: * -> *) a.
(AssertExp e, Eq a, Show a) =>
Text -> Intensional e a -> Intensional e a -> Intensional e a
assert :: Text -> Intensional e Bool -> Intensional e a -> Intensional e a
$cassert :: forall (e :: * -> *) a.
AssertExp e =>
Text -> Intensional e Bool -> Intensional e a -> Intensional e a
AssertExp
             )

liftIntensional :: (e a -> e b) -> Intensional e a -> Intensional e b
liftIntensional :: (e a -> e b) -> Intensional e a -> Intensional e b
liftIntensional e a -> e b
f (Intensional (Fold BindSet a
bsa :×: e a
ea)) = (:×:) (Fold BindSet) e b -> Intensional e b
forall (e :: * -> *) a. (:×:) (Fold BindSet) e a -> Intensional e a
Intensional (Fold BindSet a -> Fold BindSet b
coerce Fold BindSet a
bsa Fold BindSet b -> e b -> (:×:) (Fold BindSet) e b
forall (e1 :: * -> *) (e2 :: * -> *) a.
e1 a -> e2 a -> (:×:) e1 e2 a
:×: e a -> e b
f e a
ea)

liftIntensional2 ::
     (e a -> e b -> e c)
  -> Intensional e a
  -> Intensional e b
  -> Intensional e c
liftIntensional2 :: (e a -> e b -> e c)
-> Intensional e a -> Intensional e b -> Intensional e c
liftIntensional2 e a -> e b -> e c
f (Intensional (Fold BindSet a
bsa :×: e a
ea)) (Intensional (Fold BindSet b
bsb :×: e b
eb)) =
  (:×:) (Fold BindSet) e c -> Intensional e c
forall (e :: * -> *) a. (:×:) (Fold BindSet) e a -> Intensional e a
Intensional ((Fold BindSet a -> Fold BindSet c
coerce Fold BindSet a
bsa Fold BindSet c -> Fold BindSet c -> Fold BindSet c
forall a. Semigroup a => a -> a -> a
<> Fold BindSet b -> Fold BindSet c
coerce Fold BindSet b
bsb) Fold BindSet c -> e c -> (:×:) (Fold BindSet) e c
forall (e1 :: * -> *) (e2 :: * -> *) a.
e1 a -> e2 a -> (:×:) e1 e2 a
:×: e a -> e b -> e c
f e a
ea e b
eb)

liftIntensional3 ::
     (e a -> e b -> e c -> e d)
  -> Intensional e a
  -> Intensional e b
  -> Intensional e c
  -> Intensional e d
liftIntensional3 :: (e a -> e b -> e c -> e d)
-> Intensional e a
-> Intensional e b
-> Intensional e c
-> Intensional e d
liftIntensional3 e a -> e b -> e c -> e d
f
  (Intensional (Fold BindSet a
bsa :×: e a
ea))
  (Intensional (Fold BindSet b
bsb :×: e b
eb))
  (Intensional (Fold BindSet c
bsc :×: e c
ec)) =
    (:×:) (Fold BindSet) e d -> Intensional e d
forall (e :: * -> *) a. (:×:) (Fold BindSet) e a -> Intensional e a
Intensional (BindSet -> Fold BindSet d
forall e a. e -> Fold e a
Fold (Fold BindSet a -> BindSet
forall e a. Fold e a -> e
fold Fold BindSet a
bsa BindSet -> BindSet -> BindSet
forall a. Semigroup a => a -> a -> a
<> Fold BindSet b -> BindSet
forall e a. Fold e a -> e
fold Fold BindSet b
bsb BindSet -> BindSet -> BindSet
forall a. Semigroup a => a -> a -> a
<> Fold BindSet c -> BindSet
forall e a. Fold e a -> e
fold Fold BindSet c
bsc) Fold BindSet d -> e d -> (:×:) (Fold BindSet) e d
forall (e1 :: * -> *) (e2 :: * -> *) a.
e1 a -> e2 a -> (:×:) e1 e2 a
:×: e a -> e b -> e c -> e d
f e a
ea e b
eb e c
ec)

-- | Named variable expressions
--
-- This class is only used to internally to create intensional interpretations.
-- It should not be exposed to the EDSL user.
class VarExp e where
  -- | Create a named variable
  varE ::
       DinoType a
    => Text -- ^ Variable name
    -> e a

instance VarExp e => VarExp (Intensional e) where
  varE :: Text -> Intensional e a
varE Text
v = (:×:) (Fold BindSet) e a -> Intensional e a
forall (e :: * -> *) a. (:×:) (Fold BindSet) e a -> Intensional e a
Intensional (Fold BindSet a
forall a. Monoid a => a
mempty Fold BindSet a -> e a -> (:×:) (Fold BindSet) e a
forall (e1 :: * -> *) (e2 :: * -> *) a.
e1 a -> e2 a -> (:×:) e1 e2 a
:×: Text -> e a
forall (e :: * -> *) a. (VarExp e, DinoType a) => Text -> e a
varE Text
v)

-- | Open up a binder represented as a Haskell function
--
-- This function helps creating intensional interpretations of higher-order
-- constructs.
unbind ::
     (VarExp e, DinoType a)
  => Text                                 -- ^ Variable base name
  -> (Intensional e a -> Intensional e b) -- ^ Body parameterized by its free variable
  -> (Text, Intensional e b)              -- ^ Generated variable and function body
unbind :: Text
-> (Intensional e a -> Intensional e b) -> (Text, Intensional e b)
unbind Text
base Intensional e a -> Intensional e b
f = (Text
v, (:×:) (Fold BindSet) e b -> Intensional e b
forall (e :: * -> *) a. (:×:) (Fold BindSet) e a -> Intensional e a
Intensional (BindSet -> Fold BindSet b
forall e a. e -> Fold e a
Fold BindSet
bsb' Fold BindSet b -> e b -> (:×:) (Fold BindSet) e b
forall (e1 :: * -> *) (e2 :: * -> *) a.
e1 a -> e2 a -> (:×:) e1 e2 a
:×: e b
eb))
  where
    Intensional (Fold BindSet
bsb :×: e b
eb) = Intensional e a -> Intensional e b
f (Text -> Intensional e a
forall (e :: * -> *) a. (VarExp e, DinoType a) => Text -> e a
varE Text
v)
    (Text
v, BindSet
bsb') = Text -> BindSet -> (Text, BindSet)
freshVar Text
base BindSet
bsb
  -- This function uses the technique described in
  -- "Using Circular Programming for Higher-Order Syntax"
  -- <https://emilaxelsson.github.io/documents/axelsson2013using.pdf>

-- | A version of 'unbind' for 2-argument functions
unbind2 ::
     (VarExp e, DinoType a, DinoType b)
  => Text -- ^ Variable base name
  -> (Intensional e a -> Intensional e b -> Intensional e c)
       -- ^ Body parameterized by its free variables
  -> (Text, Text, Intensional e c) -- ^ Generated variables and function body
unbind2 :: Text
-> (Intensional e a -> Intensional e b -> Intensional e c)
-> (Text, Text, Intensional e c)
unbind2 Text
base Intensional e a -> Intensional e b -> Intensional e c
f = (Text
va, Text
vb, (:×:) (Fold BindSet) e c -> Intensional e c
forall (e :: * -> *) a. (:×:) (Fold BindSet) e a -> Intensional e a
Intensional (BindSet -> Fold BindSet c
forall e a. e -> Fold e a
Fold BindSet
bsc'' Fold BindSet c -> e c -> (:×:) (Fold BindSet) e c
forall (e1 :: * -> *) (e2 :: * -> *) a.
e1 a -> e2 a -> (:×:) e1 e2 a
:×: e c
ec))
  where
    Intensional (Fold BindSet
bsc :×: e c
ec) = Intensional e a -> Intensional e b -> Intensional e c
f (Text -> Intensional e a
forall (e :: * -> *) a. (VarExp e, DinoType a) => Text -> e a
varE Text
va) (Text -> Intensional e b
forall (e :: * -> *) a. (VarExp e, DinoType a) => Text -> e a
varE Text
vb)
    (Text
va, BindSet
bsc')  = Text -> BindSet -> (Text, BindSet)
freshVar Text
base BindSet
bsc
    (Text
vb, BindSet
bsc'') = Text -> BindSet -> (Text, BindSet)
freshVar Text
base BindSet
bsc'

-- | Intensional counterpart of 'CondExp'
class CondIntensional e where
  -- | Intensional counterpart of 'maybe'
  maybeI ::
       DinoType a
    => Text -- ^ Variable name
    -> e b
    -> e b -- ^ Result when 'just' (open term)
    -> e (Maybe a)
    -> e b

-- | Intensional counterpart of 'ListExp'
class ListIntensional e where
  -- | Intensional counterpart of 'mapE'
  mapI ::
       DinoType a
    => Text -- ^ Variable name
    -> e b -- ^ Body (open term)
    -> e [a]
    -> e [b]

  -- | Intensional counterpart of 'dropWhileE'
  dropWhileI ::
       DinoType a
    => Text   -- ^ Name of element variable
    -> e Bool -- ^ Predicate body (open term)
    -> e [a]
    -> e [a]

  -- | Intensional counterpart of 'foldE'
  foldI
    :: (DinoType a, DinoType b)
    => Text -- ^ Name of state variable
    -> Text -- ^ Name of element variable
    -> e a  -- ^ Body (term with two free variables)
    -> e a
    -> e [b]
    -> e a

-- | Intensional counterpart of 'LetExp'
class LetIntensional e where
  -- | Intensional counterpart of 'letE'
  letI ::
       DinoType a
    => Text -- ^ Variable name
    -> e a
    -> e b -- ^ Body (open term)
    -> e b

instance (CondExpFO e, VarExp e, CondIntensional e) =>
         CondExp (Intensional e) where
  maybe :: Intensional e b
-> (Intensional e a -> Intensional e b)
-> Intensional e (Maybe a)
-> Intensional e b
maybe Intensional e b
n Intensional e a -> Intensional e b
j = (e b -> e b -> e (Maybe a) -> e b)
-> Intensional e b
-> Intensional e b
-> Intensional e (Maybe a)
-> Intensional e b
forall (e :: * -> *) a b c d.
(e a -> e b -> e c -> e d)
-> Intensional e a
-> Intensional e b
-> Intensional e c
-> Intensional e d
liftIntensional3 (Text -> e b -> e b -> e (Maybe a) -> e b
forall (e :: * -> *) a b.
(CondIntensional e, DinoType a) =>
Text -> e b -> e b -> e (Maybe a) -> e b
maybeI Text
var) Intensional e b
n Intensional e b
body
    where
      (Text
var, Intensional e b
body) = Text
-> (Intensional e a -> Intensional e b) -> (Text, Intensional e b)
forall (e :: * -> *) a b.
(VarExp e, DinoType a) =>
Text
-> (Intensional e a -> Intensional e b) -> (Text, Intensional e b)
unbind Text
"elem" Intensional e a -> Intensional e b
j

instance (ListExpFO e, VarExp e, ListIntensional e) =>
         ListExp (Intensional e) where
  mapE :: (Intensional e a -> Intensional e b)
-> Intensional e [a] -> Intensional e [b]
mapE Intensional e a -> Intensional e b
f = (e b -> e [a] -> e [b])
-> Intensional e b -> Intensional e [a] -> Intensional e [b]
forall (e :: * -> *) a b c.
(e a -> e b -> e c)
-> Intensional e a -> Intensional e b -> Intensional e c
liftIntensional2 (Text -> e b -> e [a] -> e [b]
forall (e :: * -> *) a b.
(ListIntensional e, DinoType a) =>
Text -> e b -> e [a] -> e [b]
mapI Text
var) Intensional e b
body
    where
      (Text
var, Intensional e b
body) = Text
-> (Intensional e a -> Intensional e b) -> (Text, Intensional e b)
forall (e :: * -> *) a b.
(VarExp e, DinoType a) =>
Text
-> (Intensional e a -> Intensional e b) -> (Text, Intensional e b)
unbind Text
"elem" Intensional e a -> Intensional e b
f

  dropWhileE :: (Intensional e a -> Intensional e Bool)
-> Intensional e [a] -> Intensional e [a]
dropWhileE Intensional e a -> Intensional e Bool
f = (e Bool -> e [a] -> e [a])
-> Intensional e Bool -> Intensional e [a] -> Intensional e [a]
forall (e :: * -> *) a b c.
(e a -> e b -> e c)
-> Intensional e a -> Intensional e b -> Intensional e c
liftIntensional2 (Text -> e Bool -> e [a] -> e [a]
forall (e :: * -> *) a.
(ListIntensional e, DinoType a) =>
Text -> e Bool -> e [a] -> e [a]
dropWhileI Text
var) Intensional e Bool
body
    where
      (Text
var, Intensional e Bool
body) = Text
-> (Intensional e a -> Intensional e Bool)
-> (Text, Intensional e Bool)
forall (e :: * -> *) a b.
(VarExp e, DinoType a) =>
Text
-> (Intensional e a -> Intensional e b) -> (Text, Intensional e b)
unbind Text
"elem" Intensional e a -> Intensional e Bool
f

  foldE :: (Intensional e a -> Intensional e b -> Intensional e a)
-> Intensional e a -> Intensional e [b] -> Intensional e a
foldE Intensional e a -> Intensional e b -> Intensional e a
f = (e a -> e a -> e [b] -> e a)
-> Intensional e a
-> Intensional e a
-> Intensional e [b]
-> Intensional e a
forall (e :: * -> *) a b c d.
(e a -> e b -> e c -> e d)
-> Intensional e a
-> Intensional e b
-> Intensional e c
-> Intensional e d
liftIntensional3 (Text -> Text -> e a -> e a -> e [b] -> e a
forall (e :: * -> *) a b.
(ListIntensional e, DinoType a, DinoType b) =>
Text -> Text -> e a -> e a -> e [b] -> e a
foldI Text
va Text
vb) Intensional e a
body
    where
      (Text
va, Text
vb, Intensional e a
body) = Text
-> (Intensional e a -> Intensional e b -> Intensional e a)
-> (Text, Text, Intensional e a)
forall (e :: * -> *) a b c.
(VarExp e, DinoType a, DinoType b) =>
Text
-> (Intensional e a -> Intensional e b -> Intensional e c)
-> (Text, Text, Intensional e c)
unbind2 Text
"elem" Intensional e a -> Intensional e b -> Intensional e a
f

instance (VarExp e, LetIntensional e) => LetExp (Intensional e) where
  letE :: Text
-> Intensional e a
-> (Intensional e a -> Intensional e b)
-> Intensional e b
letE Text
base Intensional e a
a Intensional e a -> Intensional e b
f = (e a -> e b -> e b)
-> Intensional e a -> Intensional e b -> Intensional e b
forall (e :: * -> *) a b c.
(e a -> e b -> e c)
-> Intensional e a -> Intensional e b -> Intensional e c
liftIntensional2 (Text -> e a -> e b -> e b
forall (e :: * -> *) a b.
(LetIntensional e, DinoType a) =>
Text -> e a -> e b -> e b
letI Text
var) Intensional e a
a Intensional e b
body
    where
      (Text
var, Intensional e b
body) = Text
-> (Intensional e a -> Intensional e b) -> (Text, Intensional e b)
forall (e :: * -> *) a b.
(VarExp e, DinoType a) =>
Text
-> (Intensional e a -> Intensional e b) -> (Text, Intensional e b)
unbind Text
base Intensional e a -> Intensional e b
f



--------------------------------------------------------------------------------
-- * AST reification
--------------------------------------------------------------------------------

-- | Generic representation of numbers using 'Rational'
newtype NumRep = NumRep {NumRep -> Rational
unNumRep :: Rational}
  deriving (NumRep -> NumRep -> Bool
(NumRep -> NumRep -> Bool)
-> (NumRep -> NumRep -> Bool) -> Eq NumRep
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: NumRep -> NumRep -> Bool
$c/= :: NumRep -> NumRep -> Bool
== :: NumRep -> NumRep -> Bool
$c== :: NumRep -> NumRep -> Bool
Eq, Eq NumRep
Eq NumRep
-> (NumRep -> NumRep -> Ordering)
-> (NumRep -> NumRep -> Bool)
-> (NumRep -> NumRep -> Bool)
-> (NumRep -> NumRep -> Bool)
-> (NumRep -> NumRep -> Bool)
-> (NumRep -> NumRep -> NumRep)
-> (NumRep -> NumRep -> NumRep)
-> Ord NumRep
NumRep -> NumRep -> Bool
NumRep -> NumRep -> Ordering
NumRep -> NumRep -> NumRep
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: NumRep -> NumRep -> NumRep
$cmin :: NumRep -> NumRep -> NumRep
max :: NumRep -> NumRep -> NumRep
$cmax :: NumRep -> NumRep -> NumRep
>= :: NumRep -> NumRep -> Bool
$c>= :: NumRep -> NumRep -> Bool
> :: NumRep -> NumRep -> Bool
$c> :: NumRep -> NumRep -> Bool
<= :: NumRep -> NumRep -> Bool
$c<= :: NumRep -> NumRep -> Bool
< :: NumRep -> NumRep -> Bool
$c< :: NumRep -> NumRep -> Bool
compare :: NumRep -> NumRep -> Ordering
$ccompare :: NumRep -> NumRep -> Ordering
$cp1Ord :: Eq NumRep
Ord, Integer -> NumRep
NumRep -> NumRep
NumRep -> NumRep -> NumRep
(NumRep -> NumRep -> NumRep)
-> (NumRep -> NumRep -> NumRep)
-> (NumRep -> NumRep -> NumRep)
-> (NumRep -> NumRep)
-> (NumRep -> NumRep)
-> (NumRep -> NumRep)
-> (Integer -> NumRep)
-> Num NumRep
forall a.
(a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (Integer -> a)
-> Num a
fromInteger :: Integer -> NumRep
$cfromInteger :: Integer -> NumRep
signum :: NumRep -> NumRep
$csignum :: NumRep -> NumRep
abs :: NumRep -> NumRep
$cabs :: NumRep -> NumRep
negate :: NumRep -> NumRep
$cnegate :: NumRep -> NumRep
* :: NumRep -> NumRep -> NumRep
$c* :: NumRep -> NumRep -> NumRep
- :: NumRep -> NumRep -> NumRep
$c- :: NumRep -> NumRep -> NumRep
+ :: NumRep -> NumRep -> NumRep
$c+ :: NumRep -> NumRep -> NumRep
Num, Num NumRep
Num NumRep
-> (NumRep -> NumRep -> NumRep)
-> (NumRep -> NumRep)
-> (Rational -> NumRep)
-> Fractional NumRep
Rational -> NumRep
NumRep -> NumRep
NumRep -> NumRep -> NumRep
forall a.
Num a
-> (a -> a -> a) -> (a -> a) -> (Rational -> a) -> Fractional a
fromRational :: Rational -> NumRep
$cfromRational :: Rational -> NumRep
recip :: NumRep -> NumRep
$crecip :: NumRep -> NumRep
/ :: NumRep -> NumRep -> NumRep
$c/ :: NumRep -> NumRep -> NumRep
$cp1Fractional :: Num NumRep
Fractional, Num NumRep
Ord NumRep
Num NumRep -> Ord NumRep -> (NumRep -> Rational) -> Real NumRep
NumRep -> Rational
forall a. Num a -> Ord a -> (a -> Rational) -> Real a
toRational :: NumRep -> Rational
$ctoRational :: NumRep -> Rational
$cp2Real :: Ord NumRep
$cp1Real :: Num NumRep
Real, Eq NumRep
Eq NumRep
-> (Int -> NumRep -> Int) -> (NumRep -> Int) -> Hashable NumRep
Int -> NumRep -> Int
NumRep -> Int
forall a. Eq a -> (Int -> a -> Int) -> (a -> Int) -> Hashable a
hash :: NumRep -> Int
$chash :: NumRep -> Int
hashWithSalt :: Int -> NumRep -> Int
$chashWithSalt :: Int -> NumRep -> Int
$cp1Hashable :: Eq NumRep
Hashable)

-- | Integers are show exactly, non-integers are shown at 'Double' precision.
instance Show NumRep where
  show :: NumRep -> String
show (NumRep Rational
n)
    | Rational -> Integer
forall a. Ratio a -> a
denominator Rational
n Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
Prelude.== Integer
1 = Integer -> String
forall a. Show a => a -> String
show (Integer -> String) -> Integer -> String
forall a b. (a -> b) -> a -> b
$ Rational -> Integer
forall a. Ratio a -> a
numerator Rational
n
    | Bool
otherwise = Double -> String
forall a. Show a => a -> String
show (Double -> String) -> Double -> String
forall a b. (a -> b) -> a -> b
$ Rational -> Double
forall a. Fractional a => Rational -> a
fromRational @Double Rational
n

-- | Expression reified as an 'AST'
newtype Reified a = Reified {Reified a -> AST NumRep
unReified :: AST NumRep}

instance Inspectable (Reified a) where
  inspect :: Reified a -> AST Rational
inspect = Reified a -> AST Rational
coerce

appReified :: Constr -> Reified a -> Reified b
appReified :: Constr -> Reified a -> Reified b
appReified Constr
con = (AST NumRep -> AST NumRep) -> Reified a -> Reified b
coerce ((AST NumRep -> AST NumRep) -> Reified a -> Reified b)
-> (AST NumRep -> AST NumRep) -> Reified a -> Reified b
forall a b. (a -> b) -> a -> b
$ \AST NumRep
a -> Constr -> [AST NumRep] -> AST NumRep
forall n. Constr -> [AST n] -> AST n
App @NumRep Constr
con [AST NumRep
a]

appReified2 :: Constr -> Reified a -> Reified b -> Reified c
appReified2 :: Constr -> Reified a -> Reified b -> Reified c
appReified2 Constr
con = (AST NumRep -> AST NumRep -> AST NumRep)
-> Reified a -> Reified b -> Reified c
coerce ((AST NumRep -> AST NumRep -> AST NumRep)
 -> Reified a -> Reified b -> Reified c)
-> (AST NumRep -> AST NumRep -> AST NumRep)
-> Reified a
-> Reified b
-> Reified c
forall a b. (a -> b) -> a -> b
$ \AST NumRep
a AST NumRep
b -> Constr -> [AST NumRep] -> AST NumRep
forall n. Constr -> [AST n] -> AST n
App @NumRep Constr
con [AST NumRep
a, AST NumRep
b]

appReified3 :: Constr -> Reified a -> Reified b -> Reified c -> Reified d
appReified3 :: Constr -> Reified a -> Reified b -> Reified c -> Reified d
appReified3 Constr
con = (AST NumRep -> AST NumRep -> AST NumRep -> AST NumRep)
-> Reified a -> Reified b -> Reified c -> Reified d
coerce ((AST NumRep -> AST NumRep -> AST NumRep -> AST NumRep)
 -> Reified a -> Reified b -> Reified c -> Reified d)
-> (AST NumRep -> AST NumRep -> AST NumRep -> AST NumRep)
-> Reified a
-> Reified b
-> Reified c
-> Reified d
forall a b. (a -> b) -> a -> b
$ \AST NumRep
a AST NumRep
b AST NumRep
c -> Constr -> [AST NumRep] -> AST NumRep
forall n. Constr -> [AST n] -> AST n
App @NumRep Constr
con [AST NumRep
a, AST NumRep
b, AST NumRep
c]

appReified4 ::
     Constr -> Reified a -> Reified b -> Reified c -> Reified d -> Reified e
appReified4 :: Constr
-> Reified a -> Reified b -> Reified c -> Reified d -> Reified e
appReified4 Constr
con = (AST NumRep
 -> AST NumRep -> AST NumRep -> AST NumRep -> AST NumRep)
-> Reified a -> Reified b -> Reified c -> Reified d -> Reified e
coerce ((AST NumRep
  -> AST NumRep -> AST NumRep -> AST NumRep -> AST NumRep)
 -> Reified a -> Reified b -> Reified c -> Reified d -> Reified e)
-> (AST NumRep
    -> AST NumRep -> AST NumRep -> AST NumRep -> AST NumRep)
-> Reified a
-> Reified b
-> Reified c
-> Reified d
-> Reified e
forall a b. (a -> b) -> a -> b
$ \AST NumRep
a AST NumRep
b AST NumRep
c AST NumRep
d -> Constr -> [AST NumRep] -> AST NumRep
forall n. Constr -> [AST n] -> AST n
App @NumRep Constr
con [AST NumRep
a, AST NumRep
b, AST NumRep
c, AST NumRep
d]

appReified5 ::
     Constr
  -> Reified a
  -> Reified b
  -> Reified c
  -> Reified d
  -> Reified e
  -> Reified f
appReified5 :: Constr
-> Reified a
-> Reified b
-> Reified c
-> Reified d
-> Reified e
-> Reified f
appReified5 Constr
con = (AST NumRep
 -> AST NumRep
 -> AST NumRep
 -> AST NumRep
 -> AST NumRep
 -> AST NumRep)
-> Reified a
-> Reified b
-> Reified c
-> Reified d
-> Reified e
-> Reified f
coerce ((AST NumRep
  -> AST NumRep
  -> AST NumRep
  -> AST NumRep
  -> AST NumRep
  -> AST NumRep)
 -> Reified a
 -> Reified b
 -> Reified c
 -> Reified d
 -> Reified e
 -> Reified f)
-> (AST NumRep
    -> AST NumRep
    -> AST NumRep
    -> AST NumRep
    -> AST NumRep
    -> AST NumRep)
-> Reified a
-> Reified b
-> Reified c
-> Reified d
-> Reified e
-> Reified f
forall a b. (a -> b) -> a -> b
$ \AST NumRep
a AST NumRep
b AST NumRep
c AST NumRep
d AST NumRep
f -> Constr -> [AST NumRep] -> AST NumRep
forall n. Constr -> [AST n] -> AST n
App @NumRep Constr
con [AST NumRep
a, AST NumRep
b, AST NumRep
c, AST NumRep
d, AST NumRep
f]

instance ConstExp Reified where
  lit :: a -> Reified a
lit = AST Rational -> Reified a
coerce (AST Rational -> Reified a)
-> (a -> AST Rational) -> a -> Reified a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> AST Rational
forall a. Inspectable a => a -> AST Rational
inspect

instance NumExp Reified where
  add :: Reified a -> Reified a -> Reified a
add          = Constr -> Reified a -> Reified a -> Reified a
forall a b c. Constr -> Reified a -> Reified b -> Reified c
appReified2 Constr
"add"
  sub :: Reified a -> Reified a -> Reified a
sub          = Constr -> Reified a -> Reified a -> Reified a
forall a b c. Constr -> Reified a -> Reified b -> Reified c
appReified2 Constr
"sub"
  mul :: Reified a -> Reified a -> Reified a
mul          = Constr -> Reified a -> Reified a -> Reified a
forall a b c. Constr -> Reified a -> Reified b -> Reified c
appReified2 Constr
"mul"
  absE :: Reified a -> Reified a
absE         = Constr -> Reified a -> Reified a
forall a b. Constr -> Reified a -> Reified b
appReified  Constr
"absE"
  signE :: Reified a -> Reified a
signE        = Constr -> Reified a -> Reified a
forall a b. Constr -> Reified a -> Reified b
appReified  Constr
"signE"
  fromIntegral :: Reified a -> Reified b
fromIntegral = Constr -> Reified a -> Reified b
forall a b. Constr -> Reified a -> Reified b
appReified  Constr
"fromIntegral"
  floor :: Reified a -> Reified b
floor        = Constr -> Reified a -> Reified b
forall a b. Constr -> Reified a -> Reified b
appReified  Constr
"floor"
  truncate :: Reified a -> Reified b
truncate     = Constr -> Reified a -> Reified b
forall a b. Constr -> Reified a -> Reified b
appReified  Constr
"truncate"
  roundN :: Int -> Reified a -> Reified a
roundN Int
n     = Constr -> Reified Any -> Reified a -> Reified a
forall a b c. Constr -> Reified a -> Reified b -> Reified c
appReified2 Constr
"roundN" (AST NumRep -> Reified Any
forall a. AST NumRep -> Reified a
Reified (AST NumRep -> Reified Any) -> AST NumRep -> Reified Any
forall a b. (a -> b) -> a -> b
$ NumRep -> AST NumRep
forall n. n -> AST n
Number (NumRep -> AST NumRep) -> NumRep -> AST NumRep
forall a b. (a -> b) -> a -> b
$ Int -> NumRep
forall a b. (Integral a, Num b) => a -> b
Prelude.fromIntegral Int
n)

instance FracExp Reified where
  fdiv :: Reified a -> Reified a -> Reified a
fdiv = Constr -> Reified a -> Reified a -> Reified a
forall a b c. Constr -> Reified a -> Reified b -> Reified c
appReified2 Constr
"fdiv"

instance LogicExp Reified where
  not :: Reified Bool -> Reified Bool
not  = Constr -> Reified Bool -> Reified Bool
forall a b. Constr -> Reified a -> Reified b
appReified  Constr
"not"
  conj :: Reified Bool -> Reified Bool -> Reified Bool
conj = Constr -> Reified Bool -> Reified Bool -> Reified Bool
forall a b c. Constr -> Reified a -> Reified b -> Reified c
appReified2 Constr
"conj"
  disj :: Reified Bool -> Reified Bool -> Reified Bool
disj = Constr -> Reified Bool -> Reified Bool -> Reified Bool
forall a b c. Constr -> Reified a -> Reified b -> Reified c
appReified2 Constr
"disj"
  xor :: Reified Bool -> Reified Bool -> Reified Bool
xor  = Constr -> Reified Bool -> Reified Bool -> Reified Bool
forall a b c. Constr -> Reified a -> Reified b -> Reified c
appReified2 Constr
"xor"

instance CompareExp Reified where
  eq :: Reified a -> Reified a -> Reified Bool
eq  = Constr -> Reified a -> Reified a -> Reified Bool
forall a b c. Constr -> Reified a -> Reified b -> Reified c
appReified2 Constr
"eq"
  neq :: Reified a -> Reified a -> Reified Bool
neq = Constr -> Reified a -> Reified a -> Reified Bool
forall a b c. Constr -> Reified a -> Reified b -> Reified c
appReified2 Constr
"neq"
  lt :: Reified a -> Reified a -> Reified Bool
lt  = Constr -> Reified a -> Reified a -> Reified Bool
forall a b c. Constr -> Reified a -> Reified b -> Reified c
appReified2 Constr
"lt"
  gt :: Reified a -> Reified a -> Reified Bool
gt  = Constr -> Reified a -> Reified a -> Reified Bool
forall a b c. Constr -> Reified a -> Reified b -> Reified c
appReified2 Constr
"gt"
  lte :: Reified a -> Reified a -> Reified Bool
lte = Constr -> Reified a -> Reified a -> Reified Bool
forall a b c. Constr -> Reified a -> Reified b -> Reified c
appReified2 Constr
"lte"
  gte :: Reified a -> Reified a -> Reified Bool
gte = Constr -> Reified a -> Reified a -> Reified Bool
forall a b c. Constr -> Reified a -> Reified b -> Reified c
appReified2 Constr
"gte"
  min :: Reified a -> Reified a -> Reified a
min = Constr -> Reified a -> Reified a -> Reified a
forall a b c. Constr -> Reified a -> Reified b -> Reified c
appReified2 Constr
"min"
  max :: Reified a -> Reified a -> Reified a
max = Constr -> Reified a -> Reified a -> Reified a
forall a b c. Constr -> Reified a -> Reified b -> Reified c
appReified2 Constr
"max"

instance CondExpFO Reified where
  just :: Reified a -> Reified (Maybe a)
just = Constr -> Reified a -> Reified (Maybe a)
forall a b. Constr -> Reified a -> Reified b
appReified Constr
"just"

  cases :: [Reified Bool :-> Reified a]
-> (Otherwise :-> Reified a) -> Reified a
cases [Reified Bool :-> Reified a]
cs (Otherwise
Otherwise :-> Reified a
d) =
    [Reified Bool :-> Reified a] -> Reified a
forall (e :: * -> *) a.
(CondExpFO e, HasCallStack) =>
[e Bool :-> e a] -> e a
partial_cases ([Reified Bool :-> Reified a]
cs [Reified Bool :-> Reified a]
-> [Reified Bool :-> Reified a] -> [Reified Bool :-> Reified a]
forall a. [a] -> [a] -> [a]
++ [AST NumRep -> Reified Bool
forall a. AST NumRep -> Reified a
Reified (Constr -> [AST NumRep] -> AST NumRep
forall n. Constr -> [AST n] -> AST n
App Constr
"Otherwise" []) Reified Bool -> Reified a -> Reified Bool :-> Reified a
forall a b. a -> b -> a :-> b
:-> Reified a
d])

  partial_cases :: [Reified Bool :-> Reified a] -> Reified a
partial_cases [Reified Bool :-> Reified a]
cs = AST NumRep -> Reified a
forall a. AST NumRep -> Reified a
Reified (AST NumRep -> Reified a) -> AST NumRep -> Reified a
forall a b. (a -> b) -> a -> b
$ Constr -> [AST NumRep] -> AST NumRep
forall n. Constr -> [AST n] -> AST n
App Constr
"cases" ([AST NumRep] -> AST NumRep) -> [AST NumRep] -> AST NumRep
forall a b. (a -> b) -> a -> b
$ AST NumRep -> [AST NumRep]
forall (f :: * -> *) a. Applicative f => a -> f a
pure (AST NumRep -> [AST NumRep]) -> AST NumRep -> [AST NumRep]
forall a b. (a -> b) -> a -> b
$ Constr -> [AST NumRep] -> AST NumRep
forall n. Constr -> [AST n] -> AST n
App Constr
List
    [Constr -> [AST NumRep] -> AST NumRep
forall n. Constr -> [AST n] -> AST n
App Constr
":->" [Reified Bool -> AST NumRep
forall a. Reified a -> AST NumRep
unReified Reified Bool
c, Reified a -> AST NumRep
forall a. Reified a -> AST NumRep
unReified Reified a
a] | Reified Bool
c :-> Reified a
a <- [Reified Bool :-> Reified a]
cs]

instance ListExpFO Reified where
  range :: Reified a -> Reified a -> Reified [a]
range  = Constr -> Reified a -> Reified a -> Reified [a]
forall a b c. Constr -> Reified a -> Reified b -> Reified c
appReified2 Constr
"range"
  list :: [Reified a] -> Reified [a]
list   = ([AST NumRep] -> AST NumRep) -> [Reified a] -> Reified [a]
coerce (([AST NumRep] -> AST NumRep) -> [Reified a] -> Reified [a])
-> ([AST NumRep] -> AST NumRep) -> [Reified a] -> Reified [a]
forall a b. (a -> b) -> a -> b
$ Constr -> [AST NumRep] -> AST NumRep
forall n. Constr -> [AST n] -> AST n
App @NumRep Constr
List
  headE :: Reified [a] -> Reified (Maybe a)
headE  = Constr -> Reified [a] -> Reified (Maybe a)
forall a b. Constr -> Reified a -> Reified b
appReified Constr
"headE"
  append :: Reified [a] -> Reified [a] -> Reified [a]
append = Constr -> Reified [a] -> Reified [a] -> Reified [a]
forall a b c. Constr -> Reified a -> Reified b -> Reified c
appReified2 Constr
"append"

instance TupleExp Reified where
  pair :: Reified a -> Reified b -> Reified (a, b)
pair = Constr -> Reified a -> Reified b -> Reified (a, b)
forall a b c. Constr -> Reified a -> Reified b -> Reified c
appReified2 Constr
"pair"
  fstE :: Reified (a, b) -> Reified a
fstE = Constr -> Reified (a, b) -> Reified a
forall a b. Constr -> Reified a -> Reified b
appReified  Constr
"fstE"
  sndE :: Reified (a, b) -> Reified b
sndE = Constr -> Reified (a, b) -> Reified b
forall a b. Constr -> Reified a -> Reified b
appReified  Constr
"sndE"

-- | Field name prepended with @#@
instance FieldExp Reified where
  getField :: proxy f -> Reified r -> Reified a
getField proxy f
f = Constr -> Reified r -> Reified a
forall a b. Constr -> Reified a -> Reified b
appReified (String -> Constr
forall a. IsString a => String -> a
fromString (String -> Constr) -> String -> Constr
forall a b. (a -> b) -> a -> b
$ String
"#" String -> ShowS
forall a. [a] -> [a] -> [a]
++ proxy f -> String
forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal proxy f
f)

instance AnnExp Text Reified where
  ann :: Text -> Reified a -> Reified a
ann = Constr -> Reified a -> Reified a
forall a b. Constr -> Reified a -> Reified b
appReified (Constr -> Reified a -> Reified a)
-> (Text -> Constr) -> Text -> Reified a -> Reified a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NameType -> Text -> Constr
Named NameType
Annotation

-- | Ignores the assertion
instance AssertExp Reified

instance VarExp Reified where
  varE :: Text -> Reified a
varE Text
v = AST NumRep -> Reified a
forall a. AST NumRep -> Reified a
Reified (AST NumRep -> Reified a) -> AST NumRep -> Reified a
forall a b. (a -> b) -> a -> b
$ Constr -> [AST NumRep] -> AST NumRep
forall n. Constr -> [AST n] -> AST n
App (NameType -> Text -> Constr
Named NameType
LocalVar Text
v) []

instance CondIntensional Reified where
  maybeI :: Text -> Reified b -> Reified b -> Reified (Maybe a) -> Reified b
maybeI Text
v = Constr -> Reified b -> Reified b -> Reified (Maybe a) -> Reified b
forall a b c d.
Constr -> Reified a -> Reified b -> Reified c -> Reified d
appReified3 (Constr
 -> Reified b -> Reified b -> Reified (Maybe a) -> Reified b)
-> Constr
-> Reified b
-> Reified b
-> Reified (Maybe a)
-> Reified b
forall a b. (a -> b) -> a -> b
$ NameType -> Text -> Constr
Named NameType
Constructor (Text -> Constr) -> Text -> Constr
forall a b. (a -> b) -> a -> b
$ Text
"maybe *" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
v

instance ListIntensional Reified where
  mapI :: Text -> Reified b -> Reified [a] -> Reified [b]
mapI Text
v       = Constr -> Reified b -> Reified [a] -> Reified [b]
forall a b c. Constr -> Reified a -> Reified b -> Reified c
appReified2 (Constr -> Reified b -> Reified [a] -> Reified [b])
-> Constr -> Reified b -> Reified [a] -> Reified [b]
forall a b. (a -> b) -> a -> b
$ NameType -> Text -> Constr
Named NameType
Constructor (Text -> Constr) -> Text -> Constr
forall a b. (a -> b) -> a -> b
$ Text
"mapE *" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
v
  dropWhileI :: Text -> Reified Bool -> Reified [a] -> Reified [a]
dropWhileI Text
v = Constr -> Reified Bool -> Reified [a] -> Reified [a]
forall a b c. Constr -> Reified a -> Reified b -> Reified c
appReified2 (Constr -> Reified Bool -> Reified [a] -> Reified [a])
-> Constr -> Reified Bool -> Reified [a] -> Reified [a]
forall a b. (a -> b) -> a -> b
$ NameType -> Text -> Constr
Named NameType
Constructor (Text -> Constr) -> Text -> Constr
forall a b. (a -> b) -> a -> b
$ Text
"dropWhileE *" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
v
  foldI :: Text -> Text -> Reified a -> Reified a -> Reified [b] -> Reified a
foldI Text
va Text
vb  = Constr -> Reified a -> Reified a -> Reified [b] -> Reified a
forall a b c d.
Constr -> Reified a -> Reified b -> Reified c -> Reified d
appReified3 (Constr -> Reified a -> Reified a -> Reified [b] -> Reified a)
-> Constr -> Reified a -> Reified a -> Reified [b] -> Reified a
forall a b. (a -> b) -> a -> b
$
    NameType -> Text -> Constr
Named NameType
Constructor (Text -> Constr) -> Text -> Constr
forall a b. (a -> b) -> a -> b
$ [Text] -> Text
Text.unwords [Text
"foldE", Text
"*" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
va, Text
"*" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
vb]

instance LetIntensional Reified where
  letI :: Text -> Reified a -> Reified b -> Reified b
letI Text
v Reified a
a Reified b
b = ((AST NumRep -> AST NumRep -> AST NumRep)
-> Reified a -> Reified b -> Reified b
coerce ((AST NumRep -> AST NumRep -> AST NumRep)
 -> Reified a -> Reified b -> Reified b)
-> (AST NumRep -> AST NumRep -> AST NumRep)
-> Reified a
-> Reified b
-> Reified b
forall a b. (a -> b) -> a -> b
$ Text -> AST NumRep -> AST NumRep -> AST NumRep
forall n. Text -> AST n -> AST n -> AST n
Let @NumRep Text
v) Reified a
a Reified b
b



--------------------------------------------------------------------------------
-- * Evaluation with variables
--------------------------------------------------------------------------------

-- | Interpretation wrapper that evaluates using a variable environment rather
-- than piggybacking on higher-order syntax
--
-- 'EvalEnv' lacks instances of HOS classes. Instead, it provides instances of
-- 'intensional classes. In order to regain the missing HOS instances, 'EvalEnv'
-- 'can be wrapped in 'Intensional'.
--
-- @`Intensional` (`EvalEnv` e)@ is essentially equivalent to @e@, when @e@ is a
-- 'Monad'.
--
-- The purpose of 'EvalEnv' is to be used when evaluation must be done under
-- 'Intensional'. For example, this happens when combining reification and
-- evaluation.
newtype EvalEnv e a = EvalEnv
  { EvalEnv e a -> ReaderT (HashMap Text Dinamic) e a
unEvalEnv :: ReaderT (HashMap Text Dinamic) e a
  } deriving ( a -> EvalEnv e b -> EvalEnv e a
(a -> b) -> EvalEnv e a -> EvalEnv e b
(forall a b. (a -> b) -> EvalEnv e a -> EvalEnv e b)
-> (forall a b. a -> EvalEnv e b -> EvalEnv e a)
-> Functor (EvalEnv e)
forall a b. a -> EvalEnv e b -> EvalEnv e a
forall a b. (a -> b) -> EvalEnv e a -> EvalEnv e b
forall (e :: * -> *) a b.
Functor e =>
a -> EvalEnv e b -> EvalEnv e a
forall (e :: * -> *) a b.
Functor e =>
(a -> b) -> EvalEnv e a -> EvalEnv e b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: a -> EvalEnv e b -> EvalEnv e a
$c<$ :: forall (e :: * -> *) a b.
Functor e =>
a -> EvalEnv e b -> EvalEnv e a
fmap :: (a -> b) -> EvalEnv e a -> EvalEnv e b
$cfmap :: forall (e :: * -> *) a b.
Functor e =>
(a -> b) -> EvalEnv e a -> EvalEnv e b
Functor
             , Functor (EvalEnv e)
a -> EvalEnv e a
Functor (EvalEnv e)
-> (forall a. a -> EvalEnv e a)
-> (forall a b. EvalEnv e (a -> b) -> EvalEnv e a -> EvalEnv e b)
-> (forall a b c.
    (a -> b -> c) -> EvalEnv e a -> EvalEnv e b -> EvalEnv e c)
-> (forall a b. EvalEnv e a -> EvalEnv e b -> EvalEnv e b)
-> (forall a b. EvalEnv e a -> EvalEnv e b -> EvalEnv e a)
-> Applicative (EvalEnv e)
EvalEnv e a -> EvalEnv e b -> EvalEnv e b
EvalEnv e a -> EvalEnv e b -> EvalEnv e a
EvalEnv e (a -> b) -> EvalEnv e a -> EvalEnv e b
(a -> b -> c) -> EvalEnv e a -> EvalEnv e b -> EvalEnv e c
forall a. a -> EvalEnv e a
forall a b. EvalEnv e a -> EvalEnv e b -> EvalEnv e a
forall a b. EvalEnv e a -> EvalEnv e b -> EvalEnv e b
forall a b. EvalEnv e (a -> b) -> EvalEnv e a -> EvalEnv e b
forall a b c.
(a -> b -> c) -> EvalEnv e a -> EvalEnv e b -> EvalEnv e 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 (e :: * -> *). Applicative e => Functor (EvalEnv e)
forall (e :: * -> *) a. Applicative e => a -> EvalEnv e a
forall (e :: * -> *) a b.
Applicative e =>
EvalEnv e a -> EvalEnv e b -> EvalEnv e a
forall (e :: * -> *) a b.
Applicative e =>
EvalEnv e a -> EvalEnv e b -> EvalEnv e b
forall (e :: * -> *) a b.
Applicative e =>
EvalEnv e (a -> b) -> EvalEnv e a -> EvalEnv e b
forall (e :: * -> *) a b c.
Applicative e =>
(a -> b -> c) -> EvalEnv e a -> EvalEnv e b -> EvalEnv e c
<* :: EvalEnv e a -> EvalEnv e b -> EvalEnv e a
$c<* :: forall (e :: * -> *) a b.
Applicative e =>
EvalEnv e a -> EvalEnv e b -> EvalEnv e a
*> :: EvalEnv e a -> EvalEnv e b -> EvalEnv e b
$c*> :: forall (e :: * -> *) a b.
Applicative e =>
EvalEnv e a -> EvalEnv e b -> EvalEnv e b
liftA2 :: (a -> b -> c) -> EvalEnv e a -> EvalEnv e b -> EvalEnv e c
$cliftA2 :: forall (e :: * -> *) a b c.
Applicative e =>
(a -> b -> c) -> EvalEnv e a -> EvalEnv e b -> EvalEnv e c
<*> :: EvalEnv e (a -> b) -> EvalEnv e a -> EvalEnv e b
$c<*> :: forall (e :: * -> *) a b.
Applicative e =>
EvalEnv e (a -> b) -> EvalEnv e a -> EvalEnv e b
pure :: a -> EvalEnv e a
$cpure :: forall (e :: * -> *) a. Applicative e => a -> EvalEnv e a
$cp1Applicative :: forall (e :: * -> *). Applicative e => Functor (EvalEnv e)
Applicative
             , Applicative (EvalEnv e)
a -> EvalEnv e a
Applicative (EvalEnv e)
-> (forall a b. EvalEnv e a -> (a -> EvalEnv e b) -> EvalEnv e b)
-> (forall a b. EvalEnv e a -> EvalEnv e b -> EvalEnv e b)
-> (forall a. a -> EvalEnv e a)
-> Monad (EvalEnv e)
EvalEnv e a -> (a -> EvalEnv e b) -> EvalEnv e b
EvalEnv e a -> EvalEnv e b -> EvalEnv e b
forall a. a -> EvalEnv e a
forall a b. EvalEnv e a -> EvalEnv e b -> EvalEnv e b
forall a b. EvalEnv e a -> (a -> EvalEnv e b) -> EvalEnv e b
forall (e :: * -> *). Monad e => Applicative (EvalEnv e)
forall (e :: * -> *) a. Monad e => a -> EvalEnv e a
forall (e :: * -> *) a b.
Monad e =>
EvalEnv e a -> EvalEnv e b -> EvalEnv e b
forall (e :: * -> *) a b.
Monad e =>
EvalEnv e a -> (a -> EvalEnv e b) -> EvalEnv e 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
return :: a -> EvalEnv e a
$creturn :: forall (e :: * -> *) a. Monad e => a -> EvalEnv e a
>> :: EvalEnv e a -> EvalEnv e b -> EvalEnv e b
$c>> :: forall (e :: * -> *) a b.
Monad e =>
EvalEnv e a -> EvalEnv e b -> EvalEnv e b
>>= :: EvalEnv e a -> (a -> EvalEnv e b) -> EvalEnv e b
$c>>= :: forall (e :: * -> *) a b.
Monad e =>
EvalEnv e a -> (a -> EvalEnv e b) -> EvalEnv e b
$cp1Monad :: forall (e :: * -> *). Monad e => Applicative (EvalEnv e)
Monad
             , MonadReader (HashMap Text Dinamic)
             , a -> EvalEnv e a
(forall a. DinoType a => a -> EvalEnv e a) -> ConstExp (EvalEnv e)
forall a. DinoType a => a -> EvalEnv e a
forall (e :: * -> *) a.
(Applicative e, DinoType a) =>
a -> EvalEnv e a
forall (e :: * -> *).
(forall a. DinoType a => a -> e a) -> ConstExp e
lit :: a -> EvalEnv e a
$clit :: forall (e :: * -> *) a.
(Applicative e, DinoType a) =>
a -> EvalEnv e a
ConstExp
             , Int -> EvalEnv e a -> EvalEnv e a
EvalEnv e a -> EvalEnv e a -> EvalEnv e a
EvalEnv e a -> EvalEnv e a -> EvalEnv e a
EvalEnv e a -> EvalEnv e a -> EvalEnv e a
EvalEnv e a -> EvalEnv e a
EvalEnv e a -> EvalEnv e a
EvalEnv e a -> EvalEnv e b
EvalEnv e a -> EvalEnv e b
EvalEnv e a -> EvalEnv e b
(forall a. Num a => EvalEnv e a -> EvalEnv e a -> EvalEnv e a)
-> (forall a. Num a => EvalEnv e a -> EvalEnv e a -> EvalEnv e a)
-> (forall a. Num a => EvalEnv e a -> EvalEnv e a -> EvalEnv e a)
-> (forall a. Num a => EvalEnv e a -> EvalEnv e a)
-> (forall a. Num a => EvalEnv e a -> EvalEnv e a)
-> (forall a b.
    (Integral a, DinoType b, Num b) =>
    EvalEnv e a -> EvalEnv e b)
-> (forall a b.
    (RealFrac a, DinoType b, Integral b) =>
    EvalEnv e a -> EvalEnv e b)
-> (forall a b.
    (RealFrac a, DinoType b, Integral b) =>
    EvalEnv e a -> EvalEnv e b)
-> (forall a. RealFrac a => Int -> EvalEnv e a -> EvalEnv e a)
-> NumExp (EvalEnv e)
forall a. Num a => EvalEnv e a -> EvalEnv e a
forall a. Num a => EvalEnv e a -> EvalEnv e a -> EvalEnv e a
forall a. RealFrac a => Int -> EvalEnv e a -> EvalEnv e a
forall a b.
(Integral a, DinoType b, Num b) =>
EvalEnv e a -> EvalEnv e b
forall a b.
(RealFrac a, DinoType b, Integral b) =>
EvalEnv e a -> EvalEnv e b
forall (e :: * -> *) a.
(Applicative e, Num a) =>
EvalEnv e a -> EvalEnv e a
forall (e :: * -> *) a.
(Applicative e, Num a) =>
EvalEnv e a -> EvalEnv e a -> EvalEnv e a
forall (e :: * -> *) a.
(Applicative e, RealFrac a) =>
Int -> EvalEnv e a -> EvalEnv e a
forall (e :: * -> *) a b.
(Applicative e, Integral a, DinoType b, Num b) =>
EvalEnv e a -> EvalEnv e b
forall (e :: * -> *) a b.
(Applicative e, RealFrac a, DinoType b, Integral b) =>
EvalEnv e a -> EvalEnv e b
forall (e :: * -> *).
(forall a. Num a => e a -> e a -> e a)
-> (forall a. Num a => e a -> e a -> e a)
-> (forall a. Num a => e a -> e a -> e a)
-> (forall a. Num a => e a -> e a)
-> (forall a. Num a => e a -> e a)
-> (forall a b. (Integral a, DinoType b, Num b) => e a -> e b)
-> (forall a b. (RealFrac a, DinoType b, Integral b) => e a -> e b)
-> (forall a b. (RealFrac a, DinoType b, Integral b) => e a -> e b)
-> (forall a. RealFrac a => Int -> e a -> e a)
-> NumExp e
roundN :: Int -> EvalEnv e a -> EvalEnv e a
$croundN :: forall (e :: * -> *) a.
(Applicative e, RealFrac a) =>
Int -> EvalEnv e a -> EvalEnv e a
truncate :: EvalEnv e a -> EvalEnv e b
$ctruncate :: forall (e :: * -> *) a b.
(Applicative e, RealFrac a, DinoType b, Integral b) =>
EvalEnv e a -> EvalEnv e b
floor :: EvalEnv e a -> EvalEnv e b
$cfloor :: forall (e :: * -> *) a b.
(Applicative e, RealFrac a, DinoType b, Integral b) =>
EvalEnv e a -> EvalEnv e b
fromIntegral :: EvalEnv e a -> EvalEnv e b
$cfromIntegral :: forall (e :: * -> *) a b.
(Applicative e, Integral a, DinoType b, Num b) =>
EvalEnv e a -> EvalEnv e b
signE :: EvalEnv e a -> EvalEnv e a
$csignE :: forall (e :: * -> *) a.
(Applicative e, Num a) =>
EvalEnv e a -> EvalEnv e a
absE :: EvalEnv e a -> EvalEnv e a
$cabsE :: forall (e :: * -> *) a.
(Applicative e, Num a) =>
EvalEnv e a -> EvalEnv e a
mul :: EvalEnv e a -> EvalEnv e a -> EvalEnv e a
$cmul :: forall (e :: * -> *) a.
(Applicative e, Num a) =>
EvalEnv e a -> EvalEnv e a -> EvalEnv e a
sub :: EvalEnv e a -> EvalEnv e a -> EvalEnv e a
$csub :: forall (e :: * -> *) a.
(Applicative e, Num a) =>
EvalEnv e a -> EvalEnv e a -> EvalEnv e a
add :: EvalEnv e a -> EvalEnv e a -> EvalEnv e a
$cadd :: forall (e :: * -> *) a.
(Applicative e, Num a) =>
EvalEnv e a -> EvalEnv e a -> EvalEnv e a
NumExp
             , EvalEnv e a -> EvalEnv e a -> EvalEnv e a
(forall a.
 (Fractional a, Eq a) =>
 EvalEnv e a -> EvalEnv e a -> EvalEnv e a)
-> FracExp (EvalEnv e)
forall a.
(Fractional a, Eq a) =>
EvalEnv e a -> EvalEnv e a -> EvalEnv e a
forall (e :: * -> *) a.
(Applicative e, Fractional a, Eq a) =>
EvalEnv e a -> EvalEnv e a -> EvalEnv e a
forall (e :: * -> *).
(forall a. (Fractional a, Eq a) => e a -> e a -> e a) -> FracExp e
fdiv :: EvalEnv e a -> EvalEnv e a -> EvalEnv e a
$cfdiv :: forall (e :: * -> *) a.
(Applicative e, Fractional a, Eq a) =>
EvalEnv e a -> EvalEnv e a -> EvalEnv e a
FracExp
             , EvalEnv e Bool -> EvalEnv e Bool
EvalEnv e Bool -> EvalEnv e Bool -> EvalEnv e Bool
(EvalEnv e Bool -> EvalEnv e Bool)
-> (EvalEnv e Bool -> EvalEnv e Bool -> EvalEnv e Bool)
-> (EvalEnv e Bool -> EvalEnv e Bool -> EvalEnv e Bool)
-> (EvalEnv e Bool -> EvalEnv e Bool -> EvalEnv e Bool)
-> LogicExp (EvalEnv e)
forall (e :: * -> *).
Applicative e =>
EvalEnv e Bool -> EvalEnv e Bool
forall (e :: * -> *).
Applicative e =>
EvalEnv e Bool -> EvalEnv e Bool -> EvalEnv e Bool
forall (e :: * -> *).
(e Bool -> e Bool)
-> (e Bool -> e Bool -> e Bool)
-> (e Bool -> e Bool -> e Bool)
-> (e Bool -> e Bool -> e Bool)
-> LogicExp e
xor :: EvalEnv e Bool -> EvalEnv e Bool -> EvalEnv e Bool
$cxor :: forall (e :: * -> *).
Applicative e =>
EvalEnv e Bool -> EvalEnv e Bool -> EvalEnv e Bool
disj :: EvalEnv e Bool -> EvalEnv e Bool -> EvalEnv e Bool
$cdisj :: forall (e :: * -> *).
Applicative e =>
EvalEnv e Bool -> EvalEnv e Bool -> EvalEnv e Bool
conj :: EvalEnv e Bool -> EvalEnv e Bool -> EvalEnv e Bool
$cconj :: forall (e :: * -> *).
Applicative e =>
EvalEnv e Bool -> EvalEnv e Bool -> EvalEnv e Bool
not :: EvalEnv e Bool -> EvalEnv e Bool
$cnot :: forall (e :: * -> *).
Applicative e =>
EvalEnv e Bool -> EvalEnv e Bool
LogicExp
             , EvalEnv e a -> EvalEnv e a -> EvalEnv e Bool
EvalEnv e a -> EvalEnv e a -> EvalEnv e Bool
EvalEnv e a -> EvalEnv e a -> EvalEnv e Bool
EvalEnv e a -> EvalEnv e a -> EvalEnv e Bool
EvalEnv e a -> EvalEnv e a -> EvalEnv e Bool
EvalEnv e a -> EvalEnv e a -> EvalEnv e Bool
EvalEnv e a -> EvalEnv e a -> EvalEnv e a
EvalEnv e a -> EvalEnv e a -> EvalEnv e a
(forall a. Eq a => EvalEnv e a -> EvalEnv e a -> EvalEnv e Bool)
-> (forall a. Eq a => EvalEnv e a -> EvalEnv e a -> EvalEnv e Bool)
-> (forall a.
    Ord a =>
    EvalEnv e a -> EvalEnv e a -> EvalEnv e Bool)
-> (forall a.
    Ord a =>
    EvalEnv e a -> EvalEnv e a -> EvalEnv e Bool)
-> (forall a.
    Ord a =>
    EvalEnv e a -> EvalEnv e a -> EvalEnv e Bool)
-> (forall a.
    Ord a =>
    EvalEnv e a -> EvalEnv e a -> EvalEnv e Bool)
-> (forall a. Ord a => EvalEnv e a -> EvalEnv e a -> EvalEnv e a)
-> (forall a. Ord a => EvalEnv e a -> EvalEnv e a -> EvalEnv e a)
-> CompareExp (EvalEnv e)
forall a. Eq a => EvalEnv e a -> EvalEnv e a -> EvalEnv e Bool
forall a. Ord a => EvalEnv e a -> EvalEnv e a -> EvalEnv e a
forall a. Ord a => EvalEnv e a -> EvalEnv e a -> EvalEnv e Bool
forall (e :: * -> *) a.
(Applicative e, Eq a) =>
EvalEnv e a -> EvalEnv e a -> EvalEnv e Bool
forall (e :: * -> *) a.
(Applicative e, Ord a) =>
EvalEnv e a -> EvalEnv e a -> EvalEnv e a
forall (e :: * -> *) a.
(Applicative e, Ord a) =>
EvalEnv e a -> EvalEnv e a -> EvalEnv e Bool
forall (e :: * -> *).
(forall a. Eq a => e a -> e a -> e Bool)
-> (forall a. Eq a => e a -> e a -> e Bool)
-> (forall a. Ord a => e a -> e a -> e Bool)
-> (forall a. Ord a => e a -> e a -> e Bool)
-> (forall a. Ord a => e a -> e a -> e Bool)
-> (forall a. Ord a => e a -> e a -> e Bool)
-> (forall a. Ord a => e a -> e a -> e a)
-> (forall a. Ord a => e a -> e a -> e a)
-> CompareExp e
max :: EvalEnv e a -> EvalEnv e a -> EvalEnv e a
$cmax :: forall (e :: * -> *) a.
(Applicative e, Ord a) =>
EvalEnv e a -> EvalEnv e a -> EvalEnv e a
min :: EvalEnv e a -> EvalEnv e a -> EvalEnv e a
$cmin :: forall (e :: * -> *) a.
(Applicative e, Ord a) =>
EvalEnv e a -> EvalEnv e a -> EvalEnv e a
gte :: EvalEnv e a -> EvalEnv e a -> EvalEnv e Bool
$cgte :: forall (e :: * -> *) a.
(Applicative e, Ord a) =>
EvalEnv e a -> EvalEnv e a -> EvalEnv e Bool
lte :: EvalEnv e a -> EvalEnv e a -> EvalEnv e Bool
$clte :: forall (e :: * -> *) a.
(Applicative e, Ord a) =>
EvalEnv e a -> EvalEnv e a -> EvalEnv e Bool
gt :: EvalEnv e a -> EvalEnv e a -> EvalEnv e Bool
$cgt :: forall (e :: * -> *) a.
(Applicative e, Ord a) =>
EvalEnv e a -> EvalEnv e a -> EvalEnv e Bool
lt :: EvalEnv e a -> EvalEnv e a -> EvalEnv e Bool
$clt :: forall (e :: * -> *) a.
(Applicative e, Ord a) =>
EvalEnv e a -> EvalEnv e a -> EvalEnv e Bool
neq :: EvalEnv e a -> EvalEnv e a -> EvalEnv e Bool
$cneq :: forall (e :: * -> *) a.
(Applicative e, Eq a) =>
EvalEnv e a -> EvalEnv e a -> EvalEnv e Bool
eq :: EvalEnv e a -> EvalEnv e a -> EvalEnv e Bool
$ceq :: forall (e :: * -> *) a.
(Applicative e, Eq a) =>
EvalEnv e a -> EvalEnv e a -> EvalEnv e Bool
CompareExp
             , [EvalEnv e Bool :-> EvalEnv e a]
-> (Otherwise :-> EvalEnv e a) -> EvalEnv e a
[EvalEnv e Bool :-> EvalEnv e a] -> EvalEnv e a
EvalEnv e a -> EvalEnv e (Maybe a)
(forall a. EvalEnv e a -> EvalEnv e (Maybe a))
-> (forall a.
    [EvalEnv e Bool :-> EvalEnv e a]
    -> (Otherwise :-> EvalEnv e a) -> EvalEnv e a)
-> (forall a.
    HasCallStack =>
    [EvalEnv e Bool :-> EvalEnv e a] -> EvalEnv e a)
-> CondExpFO (EvalEnv e)
forall a.
HasCallStack =>
[EvalEnv e Bool :-> EvalEnv e a] -> EvalEnv e a
forall a.
[EvalEnv e Bool :-> EvalEnv e a]
-> (Otherwise :-> EvalEnv e a) -> EvalEnv e a
forall a. EvalEnv e a -> EvalEnv e (Maybe a)
forall (e :: * -> *) a.
(Monad e, HasCallStack) =>
[EvalEnv e Bool :-> EvalEnv e a] -> EvalEnv e a
forall (e :: * -> *) a.
Monad e =>
[EvalEnv e Bool :-> EvalEnv e a]
-> (Otherwise :-> EvalEnv e a) -> EvalEnv e a
forall (e :: * -> *) a.
Monad e =>
EvalEnv e a -> EvalEnv e (Maybe a)
forall (e :: * -> *).
(forall a. e a -> e (Maybe a))
-> (forall a. [e Bool :-> e a] -> (Otherwise :-> e a) -> e a)
-> (forall a. HasCallStack => [e Bool :-> e a] -> e a)
-> CondExpFO e
partial_cases :: [EvalEnv e Bool :-> EvalEnv e a] -> EvalEnv e a
$cpartial_cases :: forall (e :: * -> *) a.
(Monad e, HasCallStack) =>
[EvalEnv e Bool :-> EvalEnv e a] -> EvalEnv e a
cases :: [EvalEnv e Bool :-> EvalEnv e a]
-> (Otherwise :-> EvalEnv e a) -> EvalEnv e a
$ccases :: forall (e :: * -> *) a.
Monad e =>
[EvalEnv e Bool :-> EvalEnv e a]
-> (Otherwise :-> EvalEnv e a) -> EvalEnv e a
just :: EvalEnv e a -> EvalEnv e (Maybe a)
$cjust :: forall (e :: * -> *) a.
Monad e =>
EvalEnv e a -> EvalEnv e (Maybe a)
CondExpFO
             , [EvalEnv e a] -> EvalEnv e [a]
EvalEnv e a -> EvalEnv e a -> EvalEnv e [a]
EvalEnv e [a] -> EvalEnv e (Maybe a)
EvalEnv e [a] -> EvalEnv e [a] -> EvalEnv e [a]
(forall a. Enum a => EvalEnv e a -> EvalEnv e a -> EvalEnv e [a])
-> (forall a. DinoType a => [EvalEnv e a] -> EvalEnv e [a])
-> (forall a. EvalEnv e [a] -> EvalEnv e (Maybe a))
-> (forall a. EvalEnv e [a] -> EvalEnv e [a] -> EvalEnv e [a])
-> ListExpFO (EvalEnv e)
forall a. Enum a => EvalEnv e a -> EvalEnv e a -> EvalEnv e [a]
forall a. DinoType a => [EvalEnv e a] -> EvalEnv e [a]
forall a. EvalEnv e [a] -> EvalEnv e (Maybe a)
forall a. EvalEnv e [a] -> EvalEnv e [a] -> EvalEnv e [a]
forall (e :: * -> *) a.
(Monad e, Enum a) =>
EvalEnv e a -> EvalEnv e a -> EvalEnv e [a]
forall (e :: * -> *) a.
(Monad e, DinoType a) =>
[EvalEnv e a] -> EvalEnv e [a]
forall (e :: * -> *) a.
Monad e =>
EvalEnv e [a] -> EvalEnv e (Maybe a)
forall (e :: * -> *) a.
Monad e =>
EvalEnv e [a] -> EvalEnv e [a] -> EvalEnv e [a]
forall (e :: * -> *).
(forall a. Enum a => e a -> e a -> e [a])
-> (forall a. DinoType a => [e a] -> e [a])
-> (forall a. e [a] -> e (Maybe a))
-> (forall a. e [a] -> e [a] -> e [a])
-> ListExpFO e
append :: EvalEnv e [a] -> EvalEnv e [a] -> EvalEnv e [a]
$cappend :: forall (e :: * -> *) a.
Monad e =>
EvalEnv e [a] -> EvalEnv e [a] -> EvalEnv e [a]
headE :: EvalEnv e [a] -> EvalEnv e (Maybe a)
$cheadE :: forall (e :: * -> *) a.
Monad e =>
EvalEnv e [a] -> EvalEnv e (Maybe a)
list :: [EvalEnv e a] -> EvalEnv e [a]
$clist :: forall (e :: * -> *) a.
(Monad e, DinoType a) =>
[EvalEnv e a] -> EvalEnv e [a]
range :: EvalEnv e a -> EvalEnv e a -> EvalEnv e [a]
$crange :: forall (e :: * -> *) a.
(Monad e, Enum a) =>
EvalEnv e a -> EvalEnv e a -> EvalEnv e [a]
ListExpFO
             , EvalEnv e a -> EvalEnv e b -> EvalEnv e (a, b)
EvalEnv e (a, b) -> EvalEnv e a
EvalEnv e (a, b) -> EvalEnv e b
(forall a b. EvalEnv e a -> EvalEnv e b -> EvalEnv e (a, b))
-> (forall a b. EvalEnv e (a, b) -> EvalEnv e a)
-> (forall a b. EvalEnv e (a, b) -> EvalEnv e b)
-> TupleExp (EvalEnv e)
forall a b. EvalEnv e a -> EvalEnv e b -> EvalEnv e (a, b)
forall a b. EvalEnv e (a, b) -> EvalEnv e a
forall a b. EvalEnv e (a, b) -> EvalEnv e b
forall (e :: * -> *) a b.
Monad e =>
EvalEnv e a -> EvalEnv e b -> EvalEnv e (a, b)
forall (e :: * -> *) a b.
Monad e =>
EvalEnv e (a, b) -> EvalEnv e a
forall (e :: * -> *) a b.
Monad e =>
EvalEnv e (a, b) -> EvalEnv e b
forall (e :: * -> *).
(forall a b. e a -> e b -> e (a, b))
-> (forall a b. e (a, b) -> e a)
-> (forall a b. e (a, b) -> e b)
-> TupleExp e
sndE :: EvalEnv e (a, b) -> EvalEnv e b
$csndE :: forall (e :: * -> *) a b.
Monad e =>
EvalEnv e (a, b) -> EvalEnv e b
fstE :: EvalEnv e (a, b) -> EvalEnv e a
$cfstE :: forall (e :: * -> *) a b.
Monad e =>
EvalEnv e (a, b) -> EvalEnv e a
pair :: EvalEnv e a -> EvalEnv e b -> EvalEnv e (a, b)
$cpair :: forall (e :: * -> *) a b.
Monad e =>
EvalEnv e a -> EvalEnv e b -> EvalEnv e (a, b)
TupleExp
             , proxy f -> EvalEnv e r -> EvalEnv e a
(forall (f :: Symbol) r a (proxy :: Symbol -> *).
 (KnownSymbol f, HasField f r a, DinoType a) =>
 proxy f -> EvalEnv e r -> EvalEnv e a)
-> FieldExp (EvalEnv e)
forall (f :: Symbol) r a (proxy :: Symbol -> *).
(KnownSymbol f, HasField f r a, DinoType a) =>
proxy f -> EvalEnv e r -> EvalEnv e a
forall (e :: * -> *) (f :: Symbol) r a (proxy :: Symbol -> *).
(Monad e, KnownSymbol f, HasField f r a, DinoType a) =>
proxy f -> EvalEnv e r -> EvalEnv e a
forall (e :: * -> *).
(forall (f :: Symbol) r a (proxy :: Symbol -> *).
 (KnownSymbol f, HasField f r a, DinoType a) =>
 proxy f -> e r -> e a)
-> FieldExp e
getField :: proxy f -> EvalEnv e r -> EvalEnv e a
$cgetField :: forall (e :: * -> *) (f :: Symbol) r a (proxy :: Symbol -> *).
(Monad e, KnownSymbol f, HasField f r a, DinoType a) =>
proxy f -> EvalEnv e r -> EvalEnv e a
FieldExp
             , AnnExp ann
             )
  -- It would be possible to derive instances of `CondExp`, etc. However, that
  -- would be confusing, since `EvalEnv` is intended to be used exactly in
  -- situations where those instances cannot be used (e.g. inside
  -- `Intensional`).

-- | Add a local variable binding
extendEnv ::
     (Monad e, DinoType a)
  => Text        -- ^ Variable name
  -> a           -- ^ Value of variable
  -> EvalEnv e b -- ^ Expression to evaluate in modified environment
  -> EvalEnv e b
extendEnv :: Text -> a -> EvalEnv e b -> EvalEnv e b
extendEnv Text
var = (HashMap Text Dinamic -> HashMap Text Dinamic)
-> EvalEnv e b -> EvalEnv e b
forall r (m :: * -> *) a. MonadReader r m => (r -> r) -> m a -> m a
local ((HashMap Text Dinamic -> HashMap Text Dinamic)
 -> EvalEnv e b -> EvalEnv e b)
-> (a -> HashMap Text Dinamic -> HashMap Text Dinamic)
-> a
-> EvalEnv e b
-> EvalEnv e b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Dinamic -> HashMap Text Dinamic -> HashMap Text Dinamic
forall k v.
(Eq k, Hashable k) =>
k -> v -> HashMap k v -> HashMap k v
HashMap.insert Text
var (Dinamic -> HashMap Text Dinamic -> HashMap Text Dinamic)
-> (a -> Dinamic)
-> a
-> HashMap Text Dinamic
-> HashMap Text Dinamic
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Dinamic
forall a. DinoType a => a -> Dinamic
Dinamic

data EvalEnvError
  = NotInScope Text
  | TypeError Text
  deriving (Int -> EvalEnvError -> ShowS
[EvalEnvError] -> ShowS
EvalEnvError -> String
(Int -> EvalEnvError -> ShowS)
-> (EvalEnvError -> String)
-> ([EvalEnvError] -> ShowS)
-> Show EvalEnvError
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [EvalEnvError] -> ShowS
$cshowList :: [EvalEnvError] -> ShowS
show :: EvalEnvError -> String
$cshow :: EvalEnvError -> String
showsPrec :: Int -> EvalEnvError -> ShowS
$cshowsPrec :: Int -> EvalEnvError -> ShowS
Show)

instance Exception EvalEnvError

-- | Throws 'EvalEnvError' when variable is not in scope or has the wrong type
instance Monad e => VarExp (EvalEnv e) where
  varE :: Text -> EvalEnv e a
varE Text
var = do
    HashMap Text Dinamic
env <- EvalEnv e (HashMap Text Dinamic)
forall r (m :: * -> *). MonadReader r m => m r
ask
    a -> EvalEnv e a
forall (m :: * -> *) a. Monad m => a -> m a
return (a -> EvalEnv e a) -> a -> EvalEnv e a
forall a b. (a -> b) -> a -> b
$
      a -> (a -> a) -> Maybe a -> a
forall b a. b -> (a -> b) -> Maybe a -> b
Prelude.maybe (EvalEnvError -> a
forall a e. Exception e => e -> a
throw (EvalEnvError -> a) -> EvalEnvError -> a
forall a b. (a -> b) -> a -> b
$ Text -> EvalEnvError
TypeError Text
var) a -> a
forall a. a -> a
id (Maybe a -> a) -> Maybe a -> a
forall a b. (a -> b) -> a -> b
$
      Dinamic -> Maybe a
forall a. DinoType a => Dinamic -> Maybe a
fromDinamic (Dinamic -> Maybe a) -> Dinamic -> Maybe a
forall a b. (a -> b) -> a -> b
$
      Dinamic -> (Dinamic -> Dinamic) -> Maybe Dinamic -> Dinamic
forall b a. b -> (a -> b) -> Maybe a -> b
Prelude.maybe (EvalEnvError -> Dinamic
forall a e. Exception e => e -> a
throw (EvalEnvError -> Dinamic) -> EvalEnvError -> Dinamic
forall a b. (a -> b) -> a -> b
$ Text -> EvalEnvError
NotInScope Text
var) Dinamic -> Dinamic
forall a. a -> a
id (Maybe Dinamic -> Dinamic) -> Maybe Dinamic -> Dinamic
forall a b. (a -> b) -> a -> b
$ Text -> HashMap Text Dinamic -> Maybe Dinamic
forall k v. (Eq k, Hashable k) => k -> HashMap k v -> Maybe v
HashMap.lookup Text
var HashMap Text Dinamic
env

instance Monad e => CondIntensional (EvalEnv e) where
  maybeI :: Text
-> EvalEnv e b -> EvalEnv e b -> EvalEnv e (Maybe a) -> EvalEnv e b
maybeI Text
var EvalEnv e b
n EvalEnv e b
j EvalEnv e (Maybe a)
m = do
    Maybe a
m' <- EvalEnv e (Maybe a)
m
    case Maybe a
m' of
      Maybe a
Nothing -> EvalEnv e b
n
      Just a
a -> Text -> a -> EvalEnv e b -> EvalEnv e b
forall (e :: * -> *) a b.
(Monad e, DinoType a) =>
Text -> a -> EvalEnv e b -> EvalEnv e b
extendEnv Text
var a
a EvalEnv e b
j

instance Monad e => ListIntensional (EvalEnv e) where
  mapI :: Text -> EvalEnv e b -> EvalEnv e [a] -> EvalEnv e [b]
mapI       Text
var EvalEnv e b
body EvalEnv e [a]
as = (a -> EvalEnv e b) -> [a] -> EvalEnv e [b]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
Prelude.mapM ((a -> EvalEnv e b -> EvalEnv e b)
-> EvalEnv e b -> a -> EvalEnv e b
forall a b c. (a -> b -> c) -> b -> a -> c
flip (Text -> a -> EvalEnv e b -> EvalEnv e b
forall (e :: * -> *) a b.
(Monad e, DinoType a) =>
Text -> a -> EvalEnv e b -> EvalEnv e b
extendEnv Text
var) EvalEnv e b
body) ([a] -> EvalEnv e [b]) -> EvalEnv e [a] -> EvalEnv e [b]
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< EvalEnv e [a]
as
  dropWhileI :: Text -> EvalEnv e Bool -> EvalEnv e [a] -> EvalEnv e [a]
dropWhileI Text
var EvalEnv e Bool
body EvalEnv e [a]
as = (a -> EvalEnv e Bool) -> [a] -> EvalEnv e [a]
forall (m :: * -> *) a. Monad m => (a -> m Bool) -> [a] -> m [a]
dropWhileM   ((a -> EvalEnv e Bool -> EvalEnv e Bool)
-> EvalEnv e Bool -> a -> EvalEnv e Bool
forall a b c. (a -> b -> c) -> b -> a -> c
flip (Text -> a -> EvalEnv e Bool -> EvalEnv e Bool
forall (e :: * -> *) a b.
(Monad e, DinoType a) =>
Text -> a -> EvalEnv e b -> EvalEnv e b
extendEnv Text
var) EvalEnv e Bool
body) ([a] -> EvalEnv e [a]) -> EvalEnv e [a] -> EvalEnv e [a]
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< EvalEnv e [a]
as

  foldI :: Text
-> Text
-> EvalEnv e a
-> EvalEnv e a
-> EvalEnv e [b]
-> EvalEnv e a
foldI Text
va Text
vb EvalEnv e a
body EvalEnv e a
a EvalEnv e [b]
bs = do
    a
a' <- EvalEnv e a
a
    [b]
bs' <- EvalEnv e [b]
bs
    (a -> b -> EvalEnv e a) -> a -> [b] -> EvalEnv e a
forall (t :: * -> *) (m :: * -> *) b a.
(Foldable t, Monad m) =>
(b -> a -> m b) -> b -> t a -> m b
foldM (\a
aa b
bb -> Text -> a -> EvalEnv e a -> EvalEnv e a
forall (e :: * -> *) a b.
(Monad e, DinoType a) =>
Text -> a -> EvalEnv e b -> EvalEnv e b
extendEnv Text
va a
aa (EvalEnv e a -> EvalEnv e a) -> EvalEnv e a -> EvalEnv e a
forall a b. (a -> b) -> a -> b
$ Text -> b -> EvalEnv e a -> EvalEnv e a
forall (e :: * -> *) a b.
(Monad e, DinoType a) =>
Text -> a -> EvalEnv e b -> EvalEnv e b
extendEnv Text
vb b
bb EvalEnv e a
body) a
a' [b]
bs'

instance Monad e => LetIntensional (EvalEnv e) where
  letI :: Text -> EvalEnv e a -> EvalEnv e b -> EvalEnv e b
letI Text
var EvalEnv e a
a EvalEnv e b
b = (a -> EvalEnv e b -> EvalEnv e b)
-> EvalEnv e b -> a -> EvalEnv e b
forall a b c. (a -> b -> c) -> b -> a -> c
flip (Text -> a -> EvalEnv e b -> EvalEnv e b
forall (e :: * -> *) a b.
(Monad e, DinoType a) =>
Text -> a -> EvalEnv e b -> EvalEnv e b
extendEnv Text
var) EvalEnv e b
b (a -> EvalEnv e b) -> EvalEnv e a -> EvalEnv e b
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< EvalEnv e a
a



--------------------------------------------------------------------------------
-- * Checking assertions
--------------------------------------------------------------------------------

data InvalidAssertion
  = InvalidCondition
      { InvalidAssertion -> Text
assertionLabel :: Text
      }
  | NotEqual
      { assertionLabel :: Text
      , InvalidAssertion -> Text
reference      :: Text
      , InvalidAssertion -> Text
actual         :: Text
      }
  deriving (Int -> InvalidAssertion -> ShowS
[InvalidAssertion] -> ShowS
InvalidAssertion -> String
(Int -> InvalidAssertion -> ShowS)
-> (InvalidAssertion -> String)
-> ([InvalidAssertion] -> ShowS)
-> Show InvalidAssertion
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [InvalidAssertion] -> ShowS
$cshowList :: [InvalidAssertion] -> ShowS
show :: InvalidAssertion -> String
$cshow :: InvalidAssertion -> String
showsPrec :: Int -> InvalidAssertion -> ShowS
$cshowsPrec :: Int -> InvalidAssertion -> ShowS
Show)

instance Exception InvalidAssertion

-- | Interpretation wrapper whose 'AssertExp' instance uses 'MonadError'
newtype AssertViaMonadError e a = AssertViaMonadError
  { AssertViaMonadError e a -> e a
unAssertViaMonadError :: e a
  } deriving ( a -> AssertViaMonadError e b -> AssertViaMonadError e a
(a -> b) -> AssertViaMonadError e a -> AssertViaMonadError e b
(forall a b.
 (a -> b) -> AssertViaMonadError e a -> AssertViaMonadError e b)
-> (forall a b.
    a -> AssertViaMonadError e b -> AssertViaMonadError e a)
-> Functor (AssertViaMonadError e)
forall a b. a -> AssertViaMonadError e b -> AssertViaMonadError e a
forall a b.
(a -> b) -> AssertViaMonadError e a -> AssertViaMonadError e b
forall (e :: * -> *) a b.
Functor e =>
a -> AssertViaMonadError e b -> AssertViaMonadError e a
forall (e :: * -> *) a b.
Functor e =>
(a -> b) -> AssertViaMonadError e a -> AssertViaMonadError e b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: a -> AssertViaMonadError e b -> AssertViaMonadError e a
$c<$ :: forall (e :: * -> *) a b.
Functor e =>
a -> AssertViaMonadError e b -> AssertViaMonadError e a
fmap :: (a -> b) -> AssertViaMonadError e a -> AssertViaMonadError e b
$cfmap :: forall (e :: * -> *) a b.
Functor e =>
(a -> b) -> AssertViaMonadError e a -> AssertViaMonadError e b
Functor
             , Functor (AssertViaMonadError e)
a -> AssertViaMonadError e a
Functor (AssertViaMonadError e)
-> (forall a. a -> AssertViaMonadError e a)
-> (forall a b.
    AssertViaMonadError e (a -> b)
    -> AssertViaMonadError e a -> AssertViaMonadError e b)
-> (forall a b c.
    (a -> b -> c)
    -> AssertViaMonadError e a
    -> AssertViaMonadError e b
    -> AssertViaMonadError e c)
-> (forall a b.
    AssertViaMonadError e a
    -> AssertViaMonadError e b -> AssertViaMonadError e b)
-> (forall a b.
    AssertViaMonadError e a
    -> AssertViaMonadError e b -> AssertViaMonadError e a)
-> Applicative (AssertViaMonadError e)
AssertViaMonadError e a
-> AssertViaMonadError e b -> AssertViaMonadError e b
AssertViaMonadError e a
-> AssertViaMonadError e b -> AssertViaMonadError e a
AssertViaMonadError e (a -> b)
-> AssertViaMonadError e a -> AssertViaMonadError e b
(a -> b -> c)
-> AssertViaMonadError e a
-> AssertViaMonadError e b
-> AssertViaMonadError e c
forall a. a -> AssertViaMonadError e a
forall a b.
AssertViaMonadError e a
-> AssertViaMonadError e b -> AssertViaMonadError e a
forall a b.
AssertViaMonadError e a
-> AssertViaMonadError e b -> AssertViaMonadError e b
forall a b.
AssertViaMonadError e (a -> b)
-> AssertViaMonadError e a -> AssertViaMonadError e b
forall a b c.
(a -> b -> c)
-> AssertViaMonadError e a
-> AssertViaMonadError e b
-> AssertViaMonadError e 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 (e :: * -> *).
Applicative e =>
Functor (AssertViaMonadError e)
forall (e :: * -> *) a.
Applicative e =>
a -> AssertViaMonadError e a
forall (e :: * -> *) a b.
Applicative e =>
AssertViaMonadError e a
-> AssertViaMonadError e b -> AssertViaMonadError e a
forall (e :: * -> *) a b.
Applicative e =>
AssertViaMonadError e a
-> AssertViaMonadError e b -> AssertViaMonadError e b
forall (e :: * -> *) a b.
Applicative e =>
AssertViaMonadError e (a -> b)
-> AssertViaMonadError e a -> AssertViaMonadError e b
forall (e :: * -> *) a b c.
Applicative e =>
(a -> b -> c)
-> AssertViaMonadError e a
-> AssertViaMonadError e b
-> AssertViaMonadError e c
<* :: AssertViaMonadError e a
-> AssertViaMonadError e b -> AssertViaMonadError e a
$c<* :: forall (e :: * -> *) a b.
Applicative e =>
AssertViaMonadError e a
-> AssertViaMonadError e b -> AssertViaMonadError e a
*> :: AssertViaMonadError e a
-> AssertViaMonadError e b -> AssertViaMonadError e b
$c*> :: forall (e :: * -> *) a b.
Applicative e =>
AssertViaMonadError e a
-> AssertViaMonadError e b -> AssertViaMonadError e b
liftA2 :: (a -> b -> c)
-> AssertViaMonadError e a
-> AssertViaMonadError e b
-> AssertViaMonadError e c
$cliftA2 :: forall (e :: * -> *) a b c.
Applicative e =>
(a -> b -> c)
-> AssertViaMonadError e a
-> AssertViaMonadError e b
-> AssertViaMonadError e c
<*> :: AssertViaMonadError e (a -> b)
-> AssertViaMonadError e a -> AssertViaMonadError e b
$c<*> :: forall (e :: * -> *) a b.
Applicative e =>
AssertViaMonadError e (a -> b)
-> AssertViaMonadError e a -> AssertViaMonadError e b
pure :: a -> AssertViaMonadError e a
$cpure :: forall (e :: * -> *) a.
Applicative e =>
a -> AssertViaMonadError e a
$cp1Applicative :: forall (e :: * -> *).
Applicative e =>
Functor (AssertViaMonadError e)
Applicative
             , Applicative (AssertViaMonadError e)
a -> AssertViaMonadError e a
Applicative (AssertViaMonadError e)
-> (forall a b.
    AssertViaMonadError e a
    -> (a -> AssertViaMonadError e b) -> AssertViaMonadError e b)
-> (forall a b.
    AssertViaMonadError e a
    -> AssertViaMonadError e b -> AssertViaMonadError e b)
-> (forall a. a -> AssertViaMonadError e a)
-> Monad (AssertViaMonadError e)
AssertViaMonadError e a
-> (a -> AssertViaMonadError e b) -> AssertViaMonadError e b
AssertViaMonadError e a
-> AssertViaMonadError e b -> AssertViaMonadError e b
forall a. a -> AssertViaMonadError e a
forall a b.
AssertViaMonadError e a
-> AssertViaMonadError e b -> AssertViaMonadError e b
forall a b.
AssertViaMonadError e a
-> (a -> AssertViaMonadError e b) -> AssertViaMonadError e b
forall (e :: * -> *).
Monad e =>
Applicative (AssertViaMonadError e)
forall (e :: * -> *) a. Monad e => a -> AssertViaMonadError e a
forall (e :: * -> *) a b.
Monad e =>
AssertViaMonadError e a
-> AssertViaMonadError e b -> AssertViaMonadError e b
forall (e :: * -> *) a b.
Monad e =>
AssertViaMonadError e a
-> (a -> AssertViaMonadError e b) -> AssertViaMonadError e 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
return :: a -> AssertViaMonadError e a
$creturn :: forall (e :: * -> *) a. Monad e => a -> AssertViaMonadError e a
>> :: AssertViaMonadError e a
-> AssertViaMonadError e b -> AssertViaMonadError e b
$c>> :: forall (e :: * -> *) a b.
Monad e =>
AssertViaMonadError e a
-> AssertViaMonadError e b -> AssertViaMonadError e b
>>= :: AssertViaMonadError e a
-> (a -> AssertViaMonadError e b) -> AssertViaMonadError e b
$c>>= :: forall (e :: * -> *) a b.
Monad e =>
AssertViaMonadError e a
-> (a -> AssertViaMonadError e b) -> AssertViaMonadError e b
$cp1Monad :: forall (e :: * -> *).
Monad e =>
Applicative (AssertViaMonadError e)
Monad
             , MonadError exc
             , a -> AssertViaMonadError e a
(forall a. DinoType a => a -> AssertViaMonadError e a)
-> ConstExp (AssertViaMonadError e)
forall a. DinoType a => a -> AssertViaMonadError e a
forall (e :: * -> *) a.
(ConstExp e, DinoType a) =>
a -> AssertViaMonadError e a
forall (e :: * -> *).
(forall a. DinoType a => a -> e a) -> ConstExp e
lit :: a -> AssertViaMonadError e a
$clit :: forall (e :: * -> *) a.
(ConstExp e, DinoType a) =>
a -> AssertViaMonadError e a
ConstExp
             , Int -> AssertViaMonadError e a -> AssertViaMonadError e a
AssertViaMonadError e a
-> AssertViaMonadError e a -> AssertViaMonadError e a
AssertViaMonadError e a
-> AssertViaMonadError e a -> AssertViaMonadError e a
AssertViaMonadError e a
-> AssertViaMonadError e a -> AssertViaMonadError e a
AssertViaMonadError e a -> AssertViaMonadError e a
AssertViaMonadError e a -> AssertViaMonadError e a
AssertViaMonadError e a -> AssertViaMonadError e b
AssertViaMonadError e a -> AssertViaMonadError e b
AssertViaMonadError e a -> AssertViaMonadError e b
(forall a.
 Num a =>
 AssertViaMonadError e a
 -> AssertViaMonadError e a -> AssertViaMonadError e a)
-> (forall a.
    Num a =>
    AssertViaMonadError e a
    -> AssertViaMonadError e a -> AssertViaMonadError e a)
-> (forall a.
    Num a =>
    AssertViaMonadError e a
    -> AssertViaMonadError e a -> AssertViaMonadError e a)
-> (forall a.
    Num a =>
    AssertViaMonadError e a -> AssertViaMonadError e a)
-> (forall a.
    Num a =>
    AssertViaMonadError e a -> AssertViaMonadError e a)
-> (forall a b.
    (Integral a, DinoType b, Num b) =>
    AssertViaMonadError e a -> AssertViaMonadError e b)
-> (forall a b.
    (RealFrac a, DinoType b, Integral b) =>
    AssertViaMonadError e a -> AssertViaMonadError e b)
-> (forall a b.
    (RealFrac a, DinoType b, Integral b) =>
    AssertViaMonadError e a -> AssertViaMonadError e b)
-> (forall a.
    RealFrac a =>
    Int -> AssertViaMonadError e a -> AssertViaMonadError e a)
-> NumExp (AssertViaMonadError e)
forall a.
Num a =>
AssertViaMonadError e a -> AssertViaMonadError e a
forall a.
Num a =>
AssertViaMonadError e a
-> AssertViaMonadError e a -> AssertViaMonadError e a
forall a.
RealFrac a =>
Int -> AssertViaMonadError e a -> AssertViaMonadError e a
forall a b.
(Integral a, DinoType b, Num b) =>
AssertViaMonadError e a -> AssertViaMonadError e b
forall a b.
(RealFrac a, DinoType b, Integral b) =>
AssertViaMonadError e a -> AssertViaMonadError e b
forall (e :: * -> *) a.
(NumExp e, Num a) =>
AssertViaMonadError e a -> AssertViaMonadError e a
forall (e :: * -> *) a.
(NumExp e, Num a) =>
AssertViaMonadError e a
-> AssertViaMonadError e a -> AssertViaMonadError e a
forall (e :: * -> *) a.
(NumExp e, RealFrac a) =>
Int -> AssertViaMonadError e a -> AssertViaMonadError e a
forall (e :: * -> *) a b.
(NumExp e, Integral a, DinoType b, Num b) =>
AssertViaMonadError e a -> AssertViaMonadError e b
forall (e :: * -> *) a b.
(NumExp e, RealFrac a, DinoType b, Integral b) =>
AssertViaMonadError e a -> AssertViaMonadError e b
forall (e :: * -> *).
(forall a. Num a => e a -> e a -> e a)
-> (forall a. Num a => e a -> e a -> e a)
-> (forall a. Num a => e a -> e a -> e a)
-> (forall a. Num a => e a -> e a)
-> (forall a. Num a => e a -> e a)
-> (forall a b. (Integral a, DinoType b, Num b) => e a -> e b)
-> (forall a b. (RealFrac a, DinoType b, Integral b) => e a -> e b)
-> (forall a b. (RealFrac a, DinoType b, Integral b) => e a -> e b)
-> (forall a. RealFrac a => Int -> e a -> e a)
-> NumExp e
roundN :: Int -> AssertViaMonadError e a -> AssertViaMonadError e a
$croundN :: forall (e :: * -> *) a.
(NumExp e, RealFrac a) =>
Int -> AssertViaMonadError e a -> AssertViaMonadError e a
truncate :: AssertViaMonadError e a -> AssertViaMonadError e b
$ctruncate :: forall (e :: * -> *) a b.
(NumExp e, RealFrac a, DinoType b, Integral b) =>
AssertViaMonadError e a -> AssertViaMonadError e b
floor :: AssertViaMonadError e a -> AssertViaMonadError e b
$cfloor :: forall (e :: * -> *) a b.
(NumExp e, RealFrac a, DinoType b, Integral b) =>
AssertViaMonadError e a -> AssertViaMonadError e b
fromIntegral :: AssertViaMonadError e a -> AssertViaMonadError e b
$cfromIntegral :: forall (e :: * -> *) a b.
(NumExp e, Integral a, DinoType b, Num b) =>
AssertViaMonadError e a -> AssertViaMonadError e b
signE :: AssertViaMonadError e a -> AssertViaMonadError e a
$csignE :: forall (e :: * -> *) a.
(NumExp e, Num a) =>
AssertViaMonadError e a -> AssertViaMonadError e a
absE :: AssertViaMonadError e a -> AssertViaMonadError e a
$cabsE :: forall (e :: * -> *) a.
(NumExp e, Num a) =>
AssertViaMonadError e a -> AssertViaMonadError e a
mul :: AssertViaMonadError e a
-> AssertViaMonadError e a -> AssertViaMonadError e a
$cmul :: forall (e :: * -> *) a.
(NumExp e, Num a) =>
AssertViaMonadError e a
-> AssertViaMonadError e a -> AssertViaMonadError e a
sub :: AssertViaMonadError e a
-> AssertViaMonadError e a -> AssertViaMonadError e a
$csub :: forall (e :: * -> *) a.
(NumExp e, Num a) =>
AssertViaMonadError e a
-> AssertViaMonadError e a -> AssertViaMonadError e a
add :: AssertViaMonadError e a
-> AssertViaMonadError e a -> AssertViaMonadError e a
$cadd :: forall (e :: * -> *) a.
(NumExp e, Num a) =>
AssertViaMonadError e a
-> AssertViaMonadError e a -> AssertViaMonadError e a
NumExp
             , AssertViaMonadError e a
-> AssertViaMonadError e a -> AssertViaMonadError e a
(forall a.
 (Fractional a, Eq a) =>
 AssertViaMonadError e a
 -> AssertViaMonadError e a -> AssertViaMonadError e a)
-> FracExp (AssertViaMonadError e)
forall a.
(Fractional a, Eq a) =>
AssertViaMonadError e a
-> AssertViaMonadError e a -> AssertViaMonadError e a
forall (e :: * -> *) a.
(FracExp e, Fractional a, Eq a) =>
AssertViaMonadError e a
-> AssertViaMonadError e a -> AssertViaMonadError e a
forall (e :: * -> *).
(forall a. (Fractional a, Eq a) => e a -> e a -> e a) -> FracExp e
fdiv :: AssertViaMonadError e a
-> AssertViaMonadError e a -> AssertViaMonadError e a
$cfdiv :: forall (e :: * -> *) a.
(FracExp e, Fractional a, Eq a) =>
AssertViaMonadError e a
-> AssertViaMonadError e a -> AssertViaMonadError e a
FracExp
             , AssertViaMonadError e Bool -> AssertViaMonadError e Bool
AssertViaMonadError e Bool
-> AssertViaMonadError e Bool -> AssertViaMonadError e Bool
(AssertViaMonadError e Bool -> AssertViaMonadError e Bool)
-> (AssertViaMonadError e Bool
    -> AssertViaMonadError e Bool -> AssertViaMonadError e Bool)
-> (AssertViaMonadError e Bool
    -> AssertViaMonadError e Bool -> AssertViaMonadError e Bool)
-> (AssertViaMonadError e Bool
    -> AssertViaMonadError e Bool -> AssertViaMonadError e Bool)
-> LogicExp (AssertViaMonadError e)
forall (e :: * -> *).
LogicExp e =>
AssertViaMonadError e Bool -> AssertViaMonadError e Bool
forall (e :: * -> *).
LogicExp e =>
AssertViaMonadError e Bool
-> AssertViaMonadError e Bool -> AssertViaMonadError e Bool
forall (e :: * -> *).
(e Bool -> e Bool)
-> (e Bool -> e Bool -> e Bool)
-> (e Bool -> e Bool -> e Bool)
-> (e Bool -> e Bool -> e Bool)
-> LogicExp e
xor :: AssertViaMonadError e Bool
-> AssertViaMonadError e Bool -> AssertViaMonadError e Bool
$cxor :: forall (e :: * -> *).
LogicExp e =>
AssertViaMonadError e Bool
-> AssertViaMonadError e Bool -> AssertViaMonadError e Bool
disj :: AssertViaMonadError e Bool
-> AssertViaMonadError e Bool -> AssertViaMonadError e Bool
$cdisj :: forall (e :: * -> *).
LogicExp e =>
AssertViaMonadError e Bool
-> AssertViaMonadError e Bool -> AssertViaMonadError e Bool
conj :: AssertViaMonadError e Bool
-> AssertViaMonadError e Bool -> AssertViaMonadError e Bool
$cconj :: forall (e :: * -> *).
LogicExp e =>
AssertViaMonadError e Bool
-> AssertViaMonadError e Bool -> AssertViaMonadError e Bool
not :: AssertViaMonadError e Bool -> AssertViaMonadError e Bool
$cnot :: forall (e :: * -> *).
LogicExp e =>
AssertViaMonadError e Bool -> AssertViaMonadError e Bool
LogicExp
             , AssertViaMonadError e a
-> AssertViaMonadError e a -> AssertViaMonadError e Bool
AssertViaMonadError e a
-> AssertViaMonadError e a -> AssertViaMonadError e Bool
AssertViaMonadError e a
-> AssertViaMonadError e a -> AssertViaMonadError e Bool
AssertViaMonadError e a
-> AssertViaMonadError e a -> AssertViaMonadError e Bool
AssertViaMonadError e a
-> AssertViaMonadError e a -> AssertViaMonadError e Bool
AssertViaMonadError e a
-> AssertViaMonadError e a -> AssertViaMonadError e Bool
AssertViaMonadError e a
-> AssertViaMonadError e a -> AssertViaMonadError e a
AssertViaMonadError e a
-> AssertViaMonadError e a -> AssertViaMonadError e a
(forall a.
 Eq a =>
 AssertViaMonadError e a
 -> AssertViaMonadError e a -> AssertViaMonadError e Bool)
-> (forall a.
    Eq a =>
    AssertViaMonadError e a
    -> AssertViaMonadError e a -> AssertViaMonadError e Bool)
-> (forall a.
    Ord a =>
    AssertViaMonadError e a
    -> AssertViaMonadError e a -> AssertViaMonadError e Bool)
-> (forall a.
    Ord a =>
    AssertViaMonadError e a
    -> AssertViaMonadError e a -> AssertViaMonadError e Bool)
-> (forall a.
    Ord a =>
    AssertViaMonadError e a
    -> AssertViaMonadError e a -> AssertViaMonadError e Bool)
-> (forall a.
    Ord a =>
    AssertViaMonadError e a
    -> AssertViaMonadError e a -> AssertViaMonadError e Bool)
-> (forall a.
    Ord a =>
    AssertViaMonadError e a
    -> AssertViaMonadError e a -> AssertViaMonadError e a)
-> (forall a.
    Ord a =>
    AssertViaMonadError e a
    -> AssertViaMonadError e a -> AssertViaMonadError e a)
-> CompareExp (AssertViaMonadError e)
forall a.
Eq a =>
AssertViaMonadError e a
-> AssertViaMonadError e a -> AssertViaMonadError e Bool
forall a.
Ord a =>
AssertViaMonadError e a
-> AssertViaMonadError e a -> AssertViaMonadError e a
forall a.
Ord a =>
AssertViaMonadError e a
-> AssertViaMonadError e a -> AssertViaMonadError e Bool
forall (e :: * -> *) a.
(CompareExp e, Eq a) =>
AssertViaMonadError e a
-> AssertViaMonadError e a -> AssertViaMonadError e Bool
forall (e :: * -> *) a.
(CompareExp e, Ord a) =>
AssertViaMonadError e a
-> AssertViaMonadError e a -> AssertViaMonadError e a
forall (e :: * -> *) a.
(CompareExp e, Ord a) =>
AssertViaMonadError e a
-> AssertViaMonadError e a -> AssertViaMonadError e Bool
forall (e :: * -> *).
(forall a. Eq a => e a -> e a -> e Bool)
-> (forall a. Eq a => e a -> e a -> e Bool)
-> (forall a. Ord a => e a -> e a -> e Bool)
-> (forall a. Ord a => e a -> e a -> e Bool)
-> (forall a. Ord a => e a -> e a -> e Bool)
-> (forall a. Ord a => e a -> e a -> e Bool)
-> (forall a. Ord a => e a -> e a -> e a)
-> (forall a. Ord a => e a -> e a -> e a)
-> CompareExp e
max :: AssertViaMonadError e a
-> AssertViaMonadError e a -> AssertViaMonadError e a
$cmax :: forall (e :: * -> *) a.
(CompareExp e, Ord a) =>
AssertViaMonadError e a
-> AssertViaMonadError e a -> AssertViaMonadError e a
min :: AssertViaMonadError e a
-> AssertViaMonadError e a -> AssertViaMonadError e a
$cmin :: forall (e :: * -> *) a.
(CompareExp e, Ord a) =>
AssertViaMonadError e a
-> AssertViaMonadError e a -> AssertViaMonadError e a
gte :: AssertViaMonadError e a
-> AssertViaMonadError e a -> AssertViaMonadError e Bool
$cgte :: forall (e :: * -> *) a.
(CompareExp e, Ord a) =>
AssertViaMonadError e a
-> AssertViaMonadError e a -> AssertViaMonadError e Bool
lte :: AssertViaMonadError e a
-> AssertViaMonadError e a -> AssertViaMonadError e Bool
$clte :: forall (e :: * -> *) a.
(CompareExp e, Ord a) =>
AssertViaMonadError e a
-> AssertViaMonadError e a -> AssertViaMonadError e Bool
gt :: AssertViaMonadError e a
-> AssertViaMonadError e a -> AssertViaMonadError e Bool
$cgt :: forall (e :: * -> *) a.
(CompareExp e, Ord a) =>
AssertViaMonadError e a
-> AssertViaMonadError e a -> AssertViaMonadError e Bool
lt :: AssertViaMonadError e a
-> AssertViaMonadError e a -> AssertViaMonadError e Bool
$clt :: forall (e :: * -> *) a.
(CompareExp e, Ord a) =>
AssertViaMonadError e a
-> AssertViaMonadError e a -> AssertViaMonadError e Bool
neq :: AssertViaMonadError e a
-> AssertViaMonadError e a -> AssertViaMonadError e Bool
$cneq :: forall (e :: * -> *) a.
(CompareExp e, Eq a) =>
AssertViaMonadError e a
-> AssertViaMonadError e a -> AssertViaMonadError e Bool
eq :: AssertViaMonadError e a
-> AssertViaMonadError e a -> AssertViaMonadError e Bool
$ceq :: forall (e :: * -> *) a.
(CompareExp e, Eq a) =>
AssertViaMonadError e a
-> AssertViaMonadError e a -> AssertViaMonadError e Bool
CompareExp
             , [AssertViaMonadError e Bool :-> AssertViaMonadError e a]
-> (Otherwise :-> AssertViaMonadError e a)
-> AssertViaMonadError e a
[AssertViaMonadError e Bool :-> AssertViaMonadError e a]
-> AssertViaMonadError e a
AssertViaMonadError e a -> AssertViaMonadError e (Maybe a)
(forall a.
 AssertViaMonadError e a -> AssertViaMonadError e (Maybe a))
-> (forall a.
    [AssertViaMonadError e Bool :-> AssertViaMonadError e a]
    -> (Otherwise :-> AssertViaMonadError e a)
    -> AssertViaMonadError e a)
-> (forall a.
    HasCallStack =>
    [AssertViaMonadError e Bool :-> AssertViaMonadError e a]
    -> AssertViaMonadError e a)
-> CondExpFO (AssertViaMonadError e)
forall a.
HasCallStack =>
[AssertViaMonadError e Bool :-> AssertViaMonadError e a]
-> AssertViaMonadError e a
forall a.
[AssertViaMonadError e Bool :-> AssertViaMonadError e a]
-> (Otherwise :-> AssertViaMonadError e a)
-> AssertViaMonadError e a
forall a.
AssertViaMonadError e a -> AssertViaMonadError e (Maybe a)
forall (e :: * -> *) a.
(CondExpFO e, HasCallStack) =>
[AssertViaMonadError e Bool :-> AssertViaMonadError e a]
-> AssertViaMonadError e a
forall (e :: * -> *) a.
CondExpFO e =>
[AssertViaMonadError e Bool :-> AssertViaMonadError e a]
-> (Otherwise :-> AssertViaMonadError e a)
-> AssertViaMonadError e a
forall (e :: * -> *) a.
CondExpFO e =>
AssertViaMonadError e a -> AssertViaMonadError e (Maybe a)
forall (e :: * -> *).
(forall a. e a -> e (Maybe a))
-> (forall a. [e Bool :-> e a] -> (Otherwise :-> e a) -> e a)
-> (forall a. HasCallStack => [e Bool :-> e a] -> e a)
-> CondExpFO e
partial_cases :: [AssertViaMonadError e Bool :-> AssertViaMonadError e a]
-> AssertViaMonadError e a
$cpartial_cases :: forall (e :: * -> *) a.
(CondExpFO e, HasCallStack) =>
[AssertViaMonadError e Bool :-> AssertViaMonadError e a]
-> AssertViaMonadError e a
cases :: [AssertViaMonadError e Bool :-> AssertViaMonadError e a]
-> (Otherwise :-> AssertViaMonadError e a)
-> AssertViaMonadError e a
$ccases :: forall (e :: * -> *) a.
CondExpFO e =>
[AssertViaMonadError e Bool :-> AssertViaMonadError e a]
-> (Otherwise :-> AssertViaMonadError e a)
-> AssertViaMonadError e a
just :: AssertViaMonadError e a -> AssertViaMonadError e (Maybe a)
$cjust :: forall (e :: * -> *) a.
CondExpFO e =>
AssertViaMonadError e a -> AssertViaMonadError e (Maybe a)
CondExpFO
             , CondExpFO (AssertViaMonadError e)
CondExpFO (AssertViaMonadError e)
-> (forall a b.
    DinoType a =>
    AssertViaMonadError e b
    -> (AssertViaMonadError e a -> AssertViaMonadError e b)
    -> AssertViaMonadError e (Maybe a)
    -> AssertViaMonadError e b)
-> CondExp (AssertViaMonadError e)
AssertViaMonadError e b
-> (AssertViaMonadError e a -> AssertViaMonadError e b)
-> AssertViaMonadError e (Maybe a)
-> AssertViaMonadError e b
forall a b.
DinoType a =>
AssertViaMonadError e b
-> (AssertViaMonadError e a -> AssertViaMonadError e b)
-> AssertViaMonadError e (Maybe a)
-> AssertViaMonadError e b
forall (e :: * -> *).
CondExp e =>
CondExpFO (AssertViaMonadError e)
forall (e :: * -> *) a b.
(CondExp e, DinoType a) =>
AssertViaMonadError e b
-> (AssertViaMonadError e a -> AssertViaMonadError e b)
-> AssertViaMonadError e (Maybe a)
-> AssertViaMonadError e b
forall (e :: * -> *).
CondExpFO e
-> (forall a b.
    DinoType a =>
    e b -> (e a -> e b) -> e (Maybe a) -> e b)
-> CondExp e
maybe :: AssertViaMonadError e b
-> (AssertViaMonadError e a -> AssertViaMonadError e b)
-> AssertViaMonadError e (Maybe a)
-> AssertViaMonadError e b
$cmaybe :: forall (e :: * -> *) a b.
(CondExp e, DinoType a) =>
AssertViaMonadError e b
-> (AssertViaMonadError e a -> AssertViaMonadError e b)
-> AssertViaMonadError e (Maybe a)
-> AssertViaMonadError e b
$cp1CondExp :: forall (e :: * -> *).
CondExp e =>
CondExpFO (AssertViaMonadError e)
CondExp
             , [AssertViaMonadError e a] -> AssertViaMonadError e [a]
AssertViaMonadError e a
-> AssertViaMonadError e a -> AssertViaMonadError e [a]
AssertViaMonadError e [a] -> AssertViaMonadError e (Maybe a)
AssertViaMonadError e [a]
-> AssertViaMonadError e [a] -> AssertViaMonadError e [a]
(forall a.
 Enum a =>
 AssertViaMonadError e a
 -> AssertViaMonadError e a -> AssertViaMonadError e [a])
-> (forall a.
    DinoType a =>
    [AssertViaMonadError e a] -> AssertViaMonadError e [a])
-> (forall a.
    AssertViaMonadError e [a] -> AssertViaMonadError e (Maybe a))
-> (forall a.
    AssertViaMonadError e [a]
    -> AssertViaMonadError e [a] -> AssertViaMonadError e [a])
-> ListExpFO (AssertViaMonadError e)
forall a.
Enum a =>
AssertViaMonadError e a
-> AssertViaMonadError e a -> AssertViaMonadError e [a]
forall a.
DinoType a =>
[AssertViaMonadError e a] -> AssertViaMonadError e [a]
forall a.
AssertViaMonadError e [a] -> AssertViaMonadError e (Maybe a)
forall a.
AssertViaMonadError e [a]
-> AssertViaMonadError e [a] -> AssertViaMonadError e [a]
forall (e :: * -> *) a.
(ListExpFO e, Enum a) =>
AssertViaMonadError e a
-> AssertViaMonadError e a -> AssertViaMonadError e [a]
forall (e :: * -> *) a.
(ListExpFO e, DinoType a) =>
[AssertViaMonadError e a] -> AssertViaMonadError e [a]
forall (e :: * -> *) a.
ListExpFO e =>
AssertViaMonadError e [a] -> AssertViaMonadError e (Maybe a)
forall (e :: * -> *) a.
ListExpFO e =>
AssertViaMonadError e [a]
-> AssertViaMonadError e [a] -> AssertViaMonadError e [a]
forall (e :: * -> *).
(forall a. Enum a => e a -> e a -> e [a])
-> (forall a. DinoType a => [e a] -> e [a])
-> (forall a. e [a] -> e (Maybe a))
-> (forall a. e [a] -> e [a] -> e [a])
-> ListExpFO e
append :: AssertViaMonadError e [a]
-> AssertViaMonadError e [a] -> AssertViaMonadError e [a]
$cappend :: forall (e :: * -> *) a.
ListExpFO e =>
AssertViaMonadError e [a]
-> AssertViaMonadError e [a] -> AssertViaMonadError e [a]
headE :: AssertViaMonadError e [a] -> AssertViaMonadError e (Maybe a)
$cheadE :: forall (e :: * -> *) a.
ListExpFO e =>
AssertViaMonadError e [a] -> AssertViaMonadError e (Maybe a)
list :: [AssertViaMonadError e a] -> AssertViaMonadError e [a]
$clist :: forall (e :: * -> *) a.
(ListExpFO e, DinoType a) =>
[AssertViaMonadError e a] -> AssertViaMonadError e [a]
range :: AssertViaMonadError e a
-> AssertViaMonadError e a -> AssertViaMonadError e [a]
$crange :: forall (e :: * -> *) a.
(ListExpFO e, Enum a) =>
AssertViaMonadError e a
-> AssertViaMonadError e a -> AssertViaMonadError e [a]
ListExpFO
             , ListExpFO (AssertViaMonadError e)
ListExpFO (AssertViaMonadError e)
-> (forall a b.
    DinoType a =>
    (AssertViaMonadError e a -> AssertViaMonadError e b)
    -> AssertViaMonadError e [a] -> AssertViaMonadError e [b])
-> (forall a.
    DinoType a =>
    (AssertViaMonadError e a -> AssertViaMonadError e Bool)
    -> AssertViaMonadError e [a] -> AssertViaMonadError e [a])
-> (forall a b.
    (DinoType a, DinoType b) =>
    (AssertViaMonadError e a
     -> AssertViaMonadError e b -> AssertViaMonadError e a)
    -> AssertViaMonadError e a
    -> AssertViaMonadError e [b]
    -> AssertViaMonadError e a)
-> ListExp (AssertViaMonadError e)
(AssertViaMonadError e a -> AssertViaMonadError e b)
-> AssertViaMonadError e [a] -> AssertViaMonadError e [b]
(AssertViaMonadError e a -> AssertViaMonadError e Bool)
-> AssertViaMonadError e [a] -> AssertViaMonadError e [a]
(AssertViaMonadError e a
 -> AssertViaMonadError e b -> AssertViaMonadError e a)
-> AssertViaMonadError e a
-> AssertViaMonadError e [b]
-> AssertViaMonadError e a
forall a.
DinoType a =>
(AssertViaMonadError e a -> AssertViaMonadError e Bool)
-> AssertViaMonadError e [a] -> AssertViaMonadError e [a]
forall a b.
(DinoType a, DinoType b) =>
(AssertViaMonadError e a
 -> AssertViaMonadError e b -> AssertViaMonadError e a)
-> AssertViaMonadError e a
-> AssertViaMonadError e [b]
-> AssertViaMonadError e a
forall a b.
DinoType a =>
(AssertViaMonadError e a -> AssertViaMonadError e b)
-> AssertViaMonadError e [a] -> AssertViaMonadError e [b]
forall (e :: * -> *).
ListExp e =>
ListExpFO (AssertViaMonadError e)
forall (e :: * -> *) a.
(ListExp e, DinoType a) =>
(AssertViaMonadError e a -> AssertViaMonadError e Bool)
-> AssertViaMonadError e [a] -> AssertViaMonadError e [a]
forall (e :: * -> *) a b.
(ListExp e, DinoType a, DinoType b) =>
(AssertViaMonadError e a
 -> AssertViaMonadError e b -> AssertViaMonadError e a)
-> AssertViaMonadError e a
-> AssertViaMonadError e [b]
-> AssertViaMonadError e a
forall (e :: * -> *) a b.
(ListExp e, DinoType a) =>
(AssertViaMonadError e a -> AssertViaMonadError e b)
-> AssertViaMonadError e [a] -> AssertViaMonadError e [b]
forall (e :: * -> *).
ListExpFO e
-> (forall a b. DinoType a => (e a -> e b) -> e [a] -> e [b])
-> (forall a. DinoType a => (e a -> e Bool) -> e [a] -> e [a])
-> (forall a b.
    (DinoType a, DinoType b) =>
    (e a -> e b -> e a) -> e a -> e [b] -> e a)
-> ListExp e
foldE :: (AssertViaMonadError e a
 -> AssertViaMonadError e b -> AssertViaMonadError e a)
-> AssertViaMonadError e a
-> AssertViaMonadError e [b]
-> AssertViaMonadError e a
$cfoldE :: forall (e :: * -> *) a b.
(ListExp e, DinoType a, DinoType b) =>
(AssertViaMonadError e a
 -> AssertViaMonadError e b -> AssertViaMonadError e a)
-> AssertViaMonadError e a
-> AssertViaMonadError e [b]
-> AssertViaMonadError e a
dropWhileE :: (AssertViaMonadError e a -> AssertViaMonadError e Bool)
-> AssertViaMonadError e [a] -> AssertViaMonadError e [a]
$cdropWhileE :: forall (e :: * -> *) a.
(ListExp e, DinoType a) =>
(AssertViaMonadError e a -> AssertViaMonadError e Bool)
-> AssertViaMonadError e [a] -> AssertViaMonadError e [a]
mapE :: (AssertViaMonadError e a -> AssertViaMonadError e b)
-> AssertViaMonadError e [a] -> AssertViaMonadError e [b]
$cmapE :: forall (e :: * -> *) a b.
(ListExp e, DinoType a) =>
(AssertViaMonadError e a -> AssertViaMonadError e b)
-> AssertViaMonadError e [a] -> AssertViaMonadError e [b]
$cp1ListExp :: forall (e :: * -> *).
ListExp e =>
ListExpFO (AssertViaMonadError e)
ListExp
             , AssertViaMonadError e a
-> AssertViaMonadError e b -> AssertViaMonadError e (a, b)
AssertViaMonadError e (a, b) -> AssertViaMonadError e a
AssertViaMonadError e (a, b) -> AssertViaMonadError e b
(forall a b.
 AssertViaMonadError e a
 -> AssertViaMonadError e b -> AssertViaMonadError e (a, b))
-> (forall a b.
    AssertViaMonadError e (a, b) -> AssertViaMonadError e a)
-> (forall a b.
    AssertViaMonadError e (a, b) -> AssertViaMonadError e b)
-> TupleExp (AssertViaMonadError e)
forall a b.
AssertViaMonadError e a
-> AssertViaMonadError e b -> AssertViaMonadError e (a, b)
forall a b. AssertViaMonadError e (a, b) -> AssertViaMonadError e a
forall a b. AssertViaMonadError e (a, b) -> AssertViaMonadError e b
forall (e :: * -> *) a b.
TupleExp e =>
AssertViaMonadError e a
-> AssertViaMonadError e b -> AssertViaMonadError e (a, b)
forall (e :: * -> *) a b.
TupleExp e =>
AssertViaMonadError e (a, b) -> AssertViaMonadError e a
forall (e :: * -> *) a b.
TupleExp e =>
AssertViaMonadError e (a, b) -> AssertViaMonadError e b
forall (e :: * -> *).
(forall a b. e a -> e b -> e (a, b))
-> (forall a b. e (a, b) -> e a)
-> (forall a b. e (a, b) -> e b)
-> TupleExp e
sndE :: AssertViaMonadError e (a, b) -> AssertViaMonadError e b
$csndE :: forall (e :: * -> *) a b.
TupleExp e =>
AssertViaMonadError e (a, b) -> AssertViaMonadError e b
fstE :: AssertViaMonadError e (a, b) -> AssertViaMonadError e a
$cfstE :: forall (e :: * -> *) a b.
TupleExp e =>
AssertViaMonadError e (a, b) -> AssertViaMonadError e a
pair :: AssertViaMonadError e a
-> AssertViaMonadError e b -> AssertViaMonadError e (a, b)
$cpair :: forall (e :: * -> *) a b.
TupleExp e =>
AssertViaMonadError e a
-> AssertViaMonadError e b -> AssertViaMonadError e (a, b)
TupleExp
             , Text
-> AssertViaMonadError e a
-> (AssertViaMonadError e a -> AssertViaMonadError e b)
-> AssertViaMonadError e b
(forall a b.
 DinoType a =>
 Text
 -> AssertViaMonadError e a
 -> (AssertViaMonadError e a -> AssertViaMonadError e b)
 -> AssertViaMonadError e b)
-> LetExp (AssertViaMonadError e)
forall a b.
DinoType a =>
Text
-> AssertViaMonadError e a
-> (AssertViaMonadError e a -> AssertViaMonadError e b)
-> AssertViaMonadError e b
forall (e :: * -> *) a b.
(LetExp e, DinoType a) =>
Text
-> AssertViaMonadError e a
-> (AssertViaMonadError e a -> AssertViaMonadError e b)
-> AssertViaMonadError e b
forall (e :: * -> *).
(forall a b. DinoType a => Text -> e a -> (e a -> e b) -> e b)
-> LetExp e
letE :: Text
-> AssertViaMonadError e a
-> (AssertViaMonadError e a -> AssertViaMonadError e b)
-> AssertViaMonadError e b
$cletE :: forall (e :: * -> *) a b.
(LetExp e, DinoType a) =>
Text
-> AssertViaMonadError e a
-> (AssertViaMonadError e a -> AssertViaMonadError e b)
-> AssertViaMonadError e b
LetExp
             , proxy f -> AssertViaMonadError e r -> AssertViaMonadError e a
(forall (f :: Symbol) r a (proxy :: Symbol -> *).
 (KnownSymbol f, HasField f r a, DinoType a) =>
 proxy f -> AssertViaMonadError e r -> AssertViaMonadError e a)
-> FieldExp (AssertViaMonadError e)
forall (f :: Symbol) r a (proxy :: Symbol -> *).
(KnownSymbol f, HasField f r a, DinoType a) =>
proxy f -> AssertViaMonadError e r -> AssertViaMonadError e a
forall (e :: * -> *) (f :: Symbol) r a (proxy :: Symbol -> *).
(FieldExp e, KnownSymbol f, HasField f r a, DinoType a) =>
proxy f -> AssertViaMonadError e r -> AssertViaMonadError e a
forall (e :: * -> *).
(forall (f :: Symbol) r a (proxy :: Symbol -> *).
 (KnownSymbol f, HasField f r a, DinoType a) =>
 proxy f -> e r -> e a)
-> FieldExp e
getField :: proxy f -> AssertViaMonadError e r -> AssertViaMonadError e a
$cgetField :: forall (e :: * -> *) (f :: Symbol) r a (proxy :: Symbol -> *).
(FieldExp e, KnownSymbol f, HasField f r a, DinoType a) =>
proxy f -> AssertViaMonadError e r -> AssertViaMonadError e a
FieldExp
             , AnnExp ann
             )

-- | Throws 'InvalidAssertion' in the underlying monad
instance MonadError InvalidAssertion e =>
         AssertExp (AssertViaMonadError e) where
  assert :: Text
-> AssertViaMonadError e Bool
-> AssertViaMonadError e a
-> AssertViaMonadError e a
assert Text
lab AssertViaMonadError e Bool
cond AssertViaMonadError e a
a = do
    Bool
c <- AssertViaMonadError e Bool
cond
    Bool -> AssertViaMonadError e () -> AssertViaMonadError e ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless Bool
c (AssertViaMonadError e () -> AssertViaMonadError e ())
-> AssertViaMonadError e () -> AssertViaMonadError e ()
forall a b. (a -> b) -> a -> b
$ InvalidAssertion -> AssertViaMonadError e ()
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (InvalidAssertion -> AssertViaMonadError e ())
-> InvalidAssertion -> AssertViaMonadError e ()
forall a b. (a -> b) -> a -> b
$ Text -> InvalidAssertion
InvalidCondition Text
lab
    AssertViaMonadError e a
a

  assertEq :: Text
-> AssertViaMonadError e a
-> AssertViaMonadError e a
-> AssertViaMonadError e a
assertEq Text
lab AssertViaMonadError e a
ref AssertViaMonadError e a
act = do
    a
r <- AssertViaMonadError e a
ref
    a
a <- AssertViaMonadError e a
act
    Bool -> AssertViaMonadError e () -> AssertViaMonadError e ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (a
r a -> a -> Bool
forall a. Eq a => a -> a -> Bool
Prelude.== a
a) (AssertViaMonadError e () -> AssertViaMonadError e ())
-> AssertViaMonadError e () -> AssertViaMonadError e ()
forall a b. (a -> b) -> a -> b
$
      InvalidAssertion -> AssertViaMonadError e ()
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (InvalidAssertion -> AssertViaMonadError e ())
-> InvalidAssertion -> AssertViaMonadError e ()
forall a b. (a -> b) -> a -> b
$ Text -> Text -> Text -> InvalidAssertion
NotEqual Text
lab (String -> Text
Text.pack (String -> Text) -> String -> Text
forall a b. (a -> b) -> a -> b
$ a -> String
forall a. Show a => a -> String
show a
r) (String -> Text
Text.pack (String -> Text) -> String -> Text
forall a b. (a -> b) -> a -> b
$ a -> String
forall a. Show a => a -> String
show a
a)
    a -> AssertViaMonadError e a
forall (m :: * -> *) a. Monad m => a -> m a
return a
a

-- | Interpretation wrapper whose 'AssertExp' instance uses 'MonadThrow'
newtype AssertViaMonadThrow e a = AssertViaMonadThrow
  { AssertViaMonadThrow e a -> e a
unAssertViaMonadThrow :: e a
  } deriving ( a -> AssertViaMonadThrow e b -> AssertViaMonadThrow e a
(a -> b) -> AssertViaMonadThrow e a -> AssertViaMonadThrow e b
(forall a b.
 (a -> b) -> AssertViaMonadThrow e a -> AssertViaMonadThrow e b)
-> (forall a b.
    a -> AssertViaMonadThrow e b -> AssertViaMonadThrow e a)
-> Functor (AssertViaMonadThrow e)
forall a b. a -> AssertViaMonadThrow e b -> AssertViaMonadThrow e a
forall a b.
(a -> b) -> AssertViaMonadThrow e a -> AssertViaMonadThrow e b
forall (e :: * -> *) a b.
Functor e =>
a -> AssertViaMonadThrow e b -> AssertViaMonadThrow e a
forall (e :: * -> *) a b.
Functor e =>
(a -> b) -> AssertViaMonadThrow e a -> AssertViaMonadThrow e b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: a -> AssertViaMonadThrow e b -> AssertViaMonadThrow e a
$c<$ :: forall (e :: * -> *) a b.
Functor e =>
a -> AssertViaMonadThrow e b -> AssertViaMonadThrow e a
fmap :: (a -> b) -> AssertViaMonadThrow e a -> AssertViaMonadThrow e b
$cfmap :: forall (e :: * -> *) a b.
Functor e =>
(a -> b) -> AssertViaMonadThrow e a -> AssertViaMonadThrow e b
Functor
             , Functor (AssertViaMonadThrow e)
a -> AssertViaMonadThrow e a
Functor (AssertViaMonadThrow e)
-> (forall a. a -> AssertViaMonadThrow e a)
-> (forall a b.
    AssertViaMonadThrow e (a -> b)
    -> AssertViaMonadThrow e a -> AssertViaMonadThrow e b)
-> (forall a b c.
    (a -> b -> c)
    -> AssertViaMonadThrow e a
    -> AssertViaMonadThrow e b
    -> AssertViaMonadThrow e c)
-> (forall a b.
    AssertViaMonadThrow e a
    -> AssertViaMonadThrow e b -> AssertViaMonadThrow e b)
-> (forall a b.
    AssertViaMonadThrow e a
    -> AssertViaMonadThrow e b -> AssertViaMonadThrow e a)
-> Applicative (AssertViaMonadThrow e)
AssertViaMonadThrow e a
-> AssertViaMonadThrow e b -> AssertViaMonadThrow e b
AssertViaMonadThrow e a
-> AssertViaMonadThrow e b -> AssertViaMonadThrow e a
AssertViaMonadThrow e (a -> b)
-> AssertViaMonadThrow e a -> AssertViaMonadThrow e b
(a -> b -> c)
-> AssertViaMonadThrow e a
-> AssertViaMonadThrow e b
-> AssertViaMonadThrow e c
forall a. a -> AssertViaMonadThrow e a
forall a b.
AssertViaMonadThrow e a
-> AssertViaMonadThrow e b -> AssertViaMonadThrow e a
forall a b.
AssertViaMonadThrow e a
-> AssertViaMonadThrow e b -> AssertViaMonadThrow e b
forall a b.
AssertViaMonadThrow e (a -> b)
-> AssertViaMonadThrow e a -> AssertViaMonadThrow e b
forall a b c.
(a -> b -> c)
-> AssertViaMonadThrow e a
-> AssertViaMonadThrow e b
-> AssertViaMonadThrow e 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 (e :: * -> *).
Applicative e =>
Functor (AssertViaMonadThrow e)
forall (e :: * -> *) a.
Applicative e =>
a -> AssertViaMonadThrow e a
forall (e :: * -> *) a b.
Applicative e =>
AssertViaMonadThrow e a
-> AssertViaMonadThrow e b -> AssertViaMonadThrow e a
forall (e :: * -> *) a b.
Applicative e =>
AssertViaMonadThrow e a
-> AssertViaMonadThrow e b -> AssertViaMonadThrow e b
forall (e :: * -> *) a b.
Applicative e =>
AssertViaMonadThrow e (a -> b)
-> AssertViaMonadThrow e a -> AssertViaMonadThrow e b
forall (e :: * -> *) a b c.
Applicative e =>
(a -> b -> c)
-> AssertViaMonadThrow e a
-> AssertViaMonadThrow e b
-> AssertViaMonadThrow e c
<* :: AssertViaMonadThrow e a
-> AssertViaMonadThrow e b -> AssertViaMonadThrow e a
$c<* :: forall (e :: * -> *) a b.
Applicative e =>
AssertViaMonadThrow e a
-> AssertViaMonadThrow e b -> AssertViaMonadThrow e a
*> :: AssertViaMonadThrow e a
-> AssertViaMonadThrow e b -> AssertViaMonadThrow e b
$c*> :: forall (e :: * -> *) a b.
Applicative e =>
AssertViaMonadThrow e a
-> AssertViaMonadThrow e b -> AssertViaMonadThrow e b
liftA2 :: (a -> b -> c)
-> AssertViaMonadThrow e a
-> AssertViaMonadThrow e b
-> AssertViaMonadThrow e c
$cliftA2 :: forall (e :: * -> *) a b c.
Applicative e =>
(a -> b -> c)
-> AssertViaMonadThrow e a
-> AssertViaMonadThrow e b
-> AssertViaMonadThrow e c
<*> :: AssertViaMonadThrow e (a -> b)
-> AssertViaMonadThrow e a -> AssertViaMonadThrow e b
$c<*> :: forall (e :: * -> *) a b.
Applicative e =>
AssertViaMonadThrow e (a -> b)
-> AssertViaMonadThrow e a -> AssertViaMonadThrow e b
pure :: a -> AssertViaMonadThrow e a
$cpure :: forall (e :: * -> *) a.
Applicative e =>
a -> AssertViaMonadThrow e a
$cp1Applicative :: forall (e :: * -> *).
Applicative e =>
Functor (AssertViaMonadThrow e)
Applicative
             , Applicative (AssertViaMonadThrow e)
a -> AssertViaMonadThrow e a
Applicative (AssertViaMonadThrow e)
-> (forall a b.
    AssertViaMonadThrow e a
    -> (a -> AssertViaMonadThrow e b) -> AssertViaMonadThrow e b)
-> (forall a b.
    AssertViaMonadThrow e a
    -> AssertViaMonadThrow e b -> AssertViaMonadThrow e b)
-> (forall a. a -> AssertViaMonadThrow e a)
-> Monad (AssertViaMonadThrow e)
AssertViaMonadThrow e a
-> (a -> AssertViaMonadThrow e b) -> AssertViaMonadThrow e b
AssertViaMonadThrow e a
-> AssertViaMonadThrow e b -> AssertViaMonadThrow e b
forall a. a -> AssertViaMonadThrow e a
forall a b.
AssertViaMonadThrow e a
-> AssertViaMonadThrow e b -> AssertViaMonadThrow e b
forall a b.
AssertViaMonadThrow e a
-> (a -> AssertViaMonadThrow e b) -> AssertViaMonadThrow e b
forall (e :: * -> *).
Monad e =>
Applicative (AssertViaMonadThrow e)
forall (e :: * -> *) a. Monad e => a -> AssertViaMonadThrow e a
forall (e :: * -> *) a b.
Monad e =>
AssertViaMonadThrow e a
-> AssertViaMonadThrow e b -> AssertViaMonadThrow e b
forall (e :: * -> *) a b.
Monad e =>
AssertViaMonadThrow e a
-> (a -> AssertViaMonadThrow e b) -> AssertViaMonadThrow e 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
return :: a -> AssertViaMonadThrow e a
$creturn :: forall (e :: * -> *) a. Monad e => a -> AssertViaMonadThrow e a
>> :: AssertViaMonadThrow e a
-> AssertViaMonadThrow e b -> AssertViaMonadThrow e b
$c>> :: forall (e :: * -> *) a b.
Monad e =>
AssertViaMonadThrow e a
-> AssertViaMonadThrow e b -> AssertViaMonadThrow e b
>>= :: AssertViaMonadThrow e a
-> (a -> AssertViaMonadThrow e b) -> AssertViaMonadThrow e b
$c>>= :: forall (e :: * -> *) a b.
Monad e =>
AssertViaMonadThrow e a
-> (a -> AssertViaMonadThrow e b) -> AssertViaMonadThrow e b
$cp1Monad :: forall (e :: * -> *).
Monad e =>
Applicative (AssertViaMonadThrow e)
Monad
             , Monad (AssertViaMonadThrow e)
e -> AssertViaMonadThrow e a
Monad (AssertViaMonadThrow e)
-> (forall e a. Exception e => e -> AssertViaMonadThrow e a)
-> MonadThrow (AssertViaMonadThrow e)
forall e a. Exception e => e -> AssertViaMonadThrow e a
forall (m :: * -> *).
Monad m -> (forall e a. Exception e => e -> m a) -> MonadThrow m
forall (e :: * -> *). MonadThrow e => Monad (AssertViaMonadThrow e)
forall (e :: * -> *) e a.
(MonadThrow e, Exception e) =>
e -> AssertViaMonadThrow e a
throwM :: e -> AssertViaMonadThrow e a
$cthrowM :: forall (e :: * -> *) e a.
(MonadThrow e, Exception e) =>
e -> AssertViaMonadThrow e a
$cp1MonadThrow :: forall (e :: * -> *). MonadThrow e => Monad (AssertViaMonadThrow e)
MonadThrow
             , a -> AssertViaMonadThrow e a
(forall a. DinoType a => a -> AssertViaMonadThrow e a)
-> ConstExp (AssertViaMonadThrow e)
forall a. DinoType a => a -> AssertViaMonadThrow e a
forall (e :: * -> *) a.
(ConstExp e, DinoType a) =>
a -> AssertViaMonadThrow e a
forall (e :: * -> *).
(forall a. DinoType a => a -> e a) -> ConstExp e
lit :: a -> AssertViaMonadThrow e a
$clit :: forall (e :: * -> *) a.
(ConstExp e, DinoType a) =>
a -> AssertViaMonadThrow e a
ConstExp
             , Int -> AssertViaMonadThrow e a -> AssertViaMonadThrow e a
AssertViaMonadThrow e a
-> AssertViaMonadThrow e a -> AssertViaMonadThrow e a
AssertViaMonadThrow e a
-> AssertViaMonadThrow e a -> AssertViaMonadThrow e a
AssertViaMonadThrow e a
-> AssertViaMonadThrow e a -> AssertViaMonadThrow e a
AssertViaMonadThrow e a -> AssertViaMonadThrow e a
AssertViaMonadThrow e a -> AssertViaMonadThrow e a
AssertViaMonadThrow e a -> AssertViaMonadThrow e b
AssertViaMonadThrow e a -> AssertViaMonadThrow e b
AssertViaMonadThrow e a -> AssertViaMonadThrow e b
(forall a.
 Num a =>
 AssertViaMonadThrow e a
 -> AssertViaMonadThrow e a -> AssertViaMonadThrow e a)
-> (forall a.
    Num a =>
    AssertViaMonadThrow e a
    -> AssertViaMonadThrow e a -> AssertViaMonadThrow e a)
-> (forall a.
    Num a =>
    AssertViaMonadThrow e a
    -> AssertViaMonadThrow e a -> AssertViaMonadThrow e a)
-> (forall a.
    Num a =>
    AssertViaMonadThrow e a -> AssertViaMonadThrow e a)
-> (forall a.
    Num a =>
    AssertViaMonadThrow e a -> AssertViaMonadThrow e a)
-> (forall a b.
    (Integral a, DinoType b, Num b) =>
    AssertViaMonadThrow e a -> AssertViaMonadThrow e b)
-> (forall a b.
    (RealFrac a, DinoType b, Integral b) =>
    AssertViaMonadThrow e a -> AssertViaMonadThrow e b)
-> (forall a b.
    (RealFrac a, DinoType b, Integral b) =>
    AssertViaMonadThrow e a -> AssertViaMonadThrow e b)
-> (forall a.
    RealFrac a =>
    Int -> AssertViaMonadThrow e a -> AssertViaMonadThrow e a)
-> NumExp (AssertViaMonadThrow e)
forall a.
Num a =>
AssertViaMonadThrow e a -> AssertViaMonadThrow e a
forall a.
Num a =>
AssertViaMonadThrow e a
-> AssertViaMonadThrow e a -> AssertViaMonadThrow e a
forall a.
RealFrac a =>
Int -> AssertViaMonadThrow e a -> AssertViaMonadThrow e a
forall a b.
(Integral a, DinoType b, Num b) =>
AssertViaMonadThrow e a -> AssertViaMonadThrow e b
forall a b.
(RealFrac a, DinoType b, Integral b) =>
AssertViaMonadThrow e a -> AssertViaMonadThrow e b
forall (e :: * -> *) a.
(NumExp e, Num a) =>
AssertViaMonadThrow e a -> AssertViaMonadThrow e a
forall (e :: * -> *) a.
(NumExp e, Num a) =>
AssertViaMonadThrow e a
-> AssertViaMonadThrow e a -> AssertViaMonadThrow e a
forall (e :: * -> *) a.
(NumExp e, RealFrac a) =>
Int -> AssertViaMonadThrow e a -> AssertViaMonadThrow e a
forall (e :: * -> *) a b.
(NumExp e, Integral a, DinoType b, Num b) =>
AssertViaMonadThrow e a -> AssertViaMonadThrow e b
forall (e :: * -> *) a b.
(NumExp e, RealFrac a, DinoType b, Integral b) =>
AssertViaMonadThrow e a -> AssertViaMonadThrow e b
forall (e :: * -> *).
(forall a. Num a => e a -> e a -> e a)
-> (forall a. Num a => e a -> e a -> e a)
-> (forall a. Num a => e a -> e a -> e a)
-> (forall a. Num a => e a -> e a)
-> (forall a. Num a => e a -> e a)
-> (forall a b. (Integral a, DinoType b, Num b) => e a -> e b)
-> (forall a b. (RealFrac a, DinoType b, Integral b) => e a -> e b)
-> (forall a b. (RealFrac a, DinoType b, Integral b) => e a -> e b)
-> (forall a. RealFrac a => Int -> e a -> e a)
-> NumExp e
roundN :: Int -> AssertViaMonadThrow e a -> AssertViaMonadThrow e a
$croundN :: forall (e :: * -> *) a.
(NumExp e, RealFrac a) =>
Int -> AssertViaMonadThrow e a -> AssertViaMonadThrow e a
truncate :: AssertViaMonadThrow e a -> AssertViaMonadThrow e b
$ctruncate :: forall (e :: * -> *) a b.
(NumExp e, RealFrac a, DinoType b, Integral b) =>
AssertViaMonadThrow e a -> AssertViaMonadThrow e b
floor :: AssertViaMonadThrow e a -> AssertViaMonadThrow e b
$cfloor :: forall (e :: * -> *) a b.
(NumExp e, RealFrac a, DinoType b, Integral b) =>
AssertViaMonadThrow e a -> AssertViaMonadThrow e b
fromIntegral :: AssertViaMonadThrow e a -> AssertViaMonadThrow e b
$cfromIntegral :: forall (e :: * -> *) a b.
(NumExp e, Integral a, DinoType b, Num b) =>
AssertViaMonadThrow e a -> AssertViaMonadThrow e b
signE :: AssertViaMonadThrow e a -> AssertViaMonadThrow e a
$csignE :: forall (e :: * -> *) a.
(NumExp e, Num a) =>
AssertViaMonadThrow e a -> AssertViaMonadThrow e a
absE :: AssertViaMonadThrow e a -> AssertViaMonadThrow e a
$cabsE :: forall (e :: * -> *) a.
(NumExp e, Num a) =>
AssertViaMonadThrow e a -> AssertViaMonadThrow e a
mul :: AssertViaMonadThrow e a
-> AssertViaMonadThrow e a -> AssertViaMonadThrow e a
$cmul :: forall (e :: * -> *) a.
(NumExp e, Num a) =>
AssertViaMonadThrow e a
-> AssertViaMonadThrow e a -> AssertViaMonadThrow e a
sub :: AssertViaMonadThrow e a
-> AssertViaMonadThrow e a -> AssertViaMonadThrow e a
$csub :: forall (e :: * -> *) a.
(NumExp e, Num a) =>
AssertViaMonadThrow e a
-> AssertViaMonadThrow e a -> AssertViaMonadThrow e a
add :: AssertViaMonadThrow e a
-> AssertViaMonadThrow e a -> AssertViaMonadThrow e a
$cadd :: forall (e :: * -> *) a.
(NumExp e, Num a) =>
AssertViaMonadThrow e a
-> AssertViaMonadThrow e a -> AssertViaMonadThrow e a
NumExp
             , AssertViaMonadThrow e a
-> AssertViaMonadThrow e a -> AssertViaMonadThrow e a
(forall a.
 (Fractional a, Eq a) =>
 AssertViaMonadThrow e a
 -> AssertViaMonadThrow e a -> AssertViaMonadThrow e a)
-> FracExp (AssertViaMonadThrow e)
forall a.
(Fractional a, Eq a) =>
AssertViaMonadThrow e a
-> AssertViaMonadThrow e a -> AssertViaMonadThrow e a
forall (e :: * -> *) a.
(FracExp e, Fractional a, Eq a) =>
AssertViaMonadThrow e a
-> AssertViaMonadThrow e a -> AssertViaMonadThrow e a
forall (e :: * -> *).
(forall a. (Fractional a, Eq a) => e a -> e a -> e a) -> FracExp e
fdiv :: AssertViaMonadThrow e a
-> AssertViaMonadThrow e a -> AssertViaMonadThrow e a
$cfdiv :: forall (e :: * -> *) a.
(FracExp e, Fractional a, Eq a) =>
AssertViaMonadThrow e a
-> AssertViaMonadThrow e a -> AssertViaMonadThrow e a
FracExp
             , AssertViaMonadThrow e Bool -> AssertViaMonadThrow e Bool
AssertViaMonadThrow e Bool
-> AssertViaMonadThrow e Bool -> AssertViaMonadThrow e Bool
(AssertViaMonadThrow e Bool -> AssertViaMonadThrow e Bool)
-> (AssertViaMonadThrow e Bool
    -> AssertViaMonadThrow e Bool -> AssertViaMonadThrow e Bool)
-> (AssertViaMonadThrow e Bool
    -> AssertViaMonadThrow e Bool -> AssertViaMonadThrow e Bool)
-> (AssertViaMonadThrow e Bool
    -> AssertViaMonadThrow e Bool -> AssertViaMonadThrow e Bool)
-> LogicExp (AssertViaMonadThrow e)
forall (e :: * -> *).
LogicExp e =>
AssertViaMonadThrow e Bool -> AssertViaMonadThrow e Bool
forall (e :: * -> *).
LogicExp e =>
AssertViaMonadThrow e Bool
-> AssertViaMonadThrow e Bool -> AssertViaMonadThrow e Bool
forall (e :: * -> *).
(e Bool -> e Bool)
-> (e Bool -> e Bool -> e Bool)
-> (e Bool -> e Bool -> e Bool)
-> (e Bool -> e Bool -> e Bool)
-> LogicExp e
xor :: AssertViaMonadThrow e Bool
-> AssertViaMonadThrow e Bool -> AssertViaMonadThrow e Bool
$cxor :: forall (e :: * -> *).
LogicExp e =>
AssertViaMonadThrow e Bool
-> AssertViaMonadThrow e Bool -> AssertViaMonadThrow e Bool
disj :: AssertViaMonadThrow e Bool
-> AssertViaMonadThrow e Bool -> AssertViaMonadThrow e Bool
$cdisj :: forall (e :: * -> *).
LogicExp e =>
AssertViaMonadThrow e Bool
-> AssertViaMonadThrow e Bool -> AssertViaMonadThrow e Bool
conj :: AssertViaMonadThrow e Bool
-> AssertViaMonadThrow e Bool -> AssertViaMonadThrow e Bool
$cconj :: forall (e :: * -> *).
LogicExp e =>
AssertViaMonadThrow e Bool
-> AssertViaMonadThrow e Bool -> AssertViaMonadThrow e Bool
not :: AssertViaMonadThrow e Bool -> AssertViaMonadThrow e Bool
$cnot :: forall (e :: * -> *).
LogicExp e =>
AssertViaMonadThrow e Bool -> AssertViaMonadThrow e Bool
LogicExp
             , AssertViaMonadThrow e a
-> AssertViaMonadThrow e a -> AssertViaMonadThrow e Bool
AssertViaMonadThrow e a
-> AssertViaMonadThrow e a -> AssertViaMonadThrow e Bool
AssertViaMonadThrow e a
-> AssertViaMonadThrow e a -> AssertViaMonadThrow e Bool
AssertViaMonadThrow e a
-> AssertViaMonadThrow e a -> AssertViaMonadThrow e Bool
AssertViaMonadThrow e a
-> AssertViaMonadThrow e a -> AssertViaMonadThrow e Bool
AssertViaMonadThrow e a
-> AssertViaMonadThrow e a -> AssertViaMonadThrow e Bool
AssertViaMonadThrow e a
-> AssertViaMonadThrow e a -> AssertViaMonadThrow e a
AssertViaMonadThrow e a
-> AssertViaMonadThrow e a -> AssertViaMonadThrow e a
(forall a.
 Eq a =>
 AssertViaMonadThrow e a
 -> AssertViaMonadThrow e a -> AssertViaMonadThrow e Bool)
-> (forall a.
    Eq a =>
    AssertViaMonadThrow e a
    -> AssertViaMonadThrow e a -> AssertViaMonadThrow e Bool)
-> (forall a.
    Ord a =>
    AssertViaMonadThrow e a
    -> AssertViaMonadThrow e a -> AssertViaMonadThrow e Bool)
-> (forall a.
    Ord a =>
    AssertViaMonadThrow e a
    -> AssertViaMonadThrow e a -> AssertViaMonadThrow e Bool)
-> (forall a.
    Ord a =>
    AssertViaMonadThrow e a
    -> AssertViaMonadThrow e a -> AssertViaMonadThrow e Bool)
-> (forall a.
    Ord a =>
    AssertViaMonadThrow e a
    -> AssertViaMonadThrow e a -> AssertViaMonadThrow e Bool)
-> (forall a.
    Ord a =>
    AssertViaMonadThrow e a
    -> AssertViaMonadThrow e a -> AssertViaMonadThrow e a)
-> (forall a.
    Ord a =>
    AssertViaMonadThrow e a
    -> AssertViaMonadThrow e a -> AssertViaMonadThrow e a)
-> CompareExp (AssertViaMonadThrow e)
forall a.
Eq a =>
AssertViaMonadThrow e a
-> AssertViaMonadThrow e a -> AssertViaMonadThrow e Bool
forall a.
Ord a =>
AssertViaMonadThrow e a
-> AssertViaMonadThrow e a -> AssertViaMonadThrow e a
forall a.
Ord a =>
AssertViaMonadThrow e a
-> AssertViaMonadThrow e a -> AssertViaMonadThrow e Bool
forall (e :: * -> *) a.
(CompareExp e, Eq a) =>
AssertViaMonadThrow e a
-> AssertViaMonadThrow e a -> AssertViaMonadThrow e Bool
forall (e :: * -> *) a.
(CompareExp e, Ord a) =>
AssertViaMonadThrow e a
-> AssertViaMonadThrow e a -> AssertViaMonadThrow e a
forall (e :: * -> *) a.
(CompareExp e, Ord a) =>
AssertViaMonadThrow e a
-> AssertViaMonadThrow e a -> AssertViaMonadThrow e Bool
forall (e :: * -> *).
(forall a. Eq a => e a -> e a -> e Bool)
-> (forall a. Eq a => e a -> e a -> e Bool)
-> (forall a. Ord a => e a -> e a -> e Bool)
-> (forall a. Ord a => e a -> e a -> e Bool)
-> (forall a. Ord a => e a -> e a -> e Bool)
-> (forall a. Ord a => e a -> e a -> e Bool)
-> (forall a. Ord a => e a -> e a -> e a)
-> (forall a. Ord a => e a -> e a -> e a)
-> CompareExp e
max :: AssertViaMonadThrow e a
-> AssertViaMonadThrow e a -> AssertViaMonadThrow e a
$cmax :: forall (e :: * -> *) a.
(CompareExp e, Ord a) =>
AssertViaMonadThrow e a
-> AssertViaMonadThrow e a -> AssertViaMonadThrow e a
min :: AssertViaMonadThrow e a
-> AssertViaMonadThrow e a -> AssertViaMonadThrow e a
$cmin :: forall (e :: * -> *) a.
(CompareExp e, Ord a) =>
AssertViaMonadThrow e a
-> AssertViaMonadThrow e a -> AssertViaMonadThrow e a
gte :: AssertViaMonadThrow e a
-> AssertViaMonadThrow e a -> AssertViaMonadThrow e Bool
$cgte :: forall (e :: * -> *) a.
(CompareExp e, Ord a) =>
AssertViaMonadThrow e a
-> AssertViaMonadThrow e a -> AssertViaMonadThrow e Bool
lte :: AssertViaMonadThrow e a
-> AssertViaMonadThrow e a -> AssertViaMonadThrow e Bool
$clte :: forall (e :: * -> *) a.
(CompareExp e, Ord a) =>
AssertViaMonadThrow e a
-> AssertViaMonadThrow e a -> AssertViaMonadThrow e Bool
gt :: AssertViaMonadThrow e a
-> AssertViaMonadThrow e a -> AssertViaMonadThrow e Bool
$cgt :: forall (e :: * -> *) a.
(CompareExp e, Ord a) =>
AssertViaMonadThrow e a
-> AssertViaMonadThrow e a -> AssertViaMonadThrow e Bool
lt :: AssertViaMonadThrow e a
-> AssertViaMonadThrow e a -> AssertViaMonadThrow e Bool
$clt :: forall (e :: * -> *) a.
(CompareExp e, Ord a) =>
AssertViaMonadThrow e a
-> AssertViaMonadThrow e a -> AssertViaMonadThrow e Bool
neq :: AssertViaMonadThrow e a
-> AssertViaMonadThrow e a -> AssertViaMonadThrow e Bool
$cneq :: forall (e :: * -> *) a.
(CompareExp e, Eq a) =>
AssertViaMonadThrow e a
-> AssertViaMonadThrow e a -> AssertViaMonadThrow e Bool
eq :: AssertViaMonadThrow e a
-> AssertViaMonadThrow e a -> AssertViaMonadThrow e Bool
$ceq :: forall (e :: * -> *) a.
(CompareExp e, Eq a) =>
AssertViaMonadThrow e a
-> AssertViaMonadThrow e a -> AssertViaMonadThrow e Bool
CompareExp
             , [AssertViaMonadThrow e Bool :-> AssertViaMonadThrow e a]
-> (Otherwise :-> AssertViaMonadThrow e a)
-> AssertViaMonadThrow e a
[AssertViaMonadThrow e Bool :-> AssertViaMonadThrow e a]
-> AssertViaMonadThrow e a
AssertViaMonadThrow e a -> AssertViaMonadThrow e (Maybe a)
(forall a.
 AssertViaMonadThrow e a -> AssertViaMonadThrow e (Maybe a))
-> (forall a.
    [AssertViaMonadThrow e Bool :-> AssertViaMonadThrow e a]
    -> (Otherwise :-> AssertViaMonadThrow e a)
    -> AssertViaMonadThrow e a)
-> (forall a.
    HasCallStack =>
    [AssertViaMonadThrow e Bool :-> AssertViaMonadThrow e a]
    -> AssertViaMonadThrow e a)
-> CondExpFO (AssertViaMonadThrow e)
forall a.
HasCallStack =>
[AssertViaMonadThrow e Bool :-> AssertViaMonadThrow e a]
-> AssertViaMonadThrow e a
forall a.
[AssertViaMonadThrow e Bool :-> AssertViaMonadThrow e a]
-> (Otherwise :-> AssertViaMonadThrow e a)
-> AssertViaMonadThrow e a
forall a.
AssertViaMonadThrow e a -> AssertViaMonadThrow e (Maybe a)
forall (e :: * -> *) a.
(CondExpFO e, HasCallStack) =>
[AssertViaMonadThrow e Bool :-> AssertViaMonadThrow e a]
-> AssertViaMonadThrow e a
forall (e :: * -> *) a.
CondExpFO e =>
[AssertViaMonadThrow e Bool :-> AssertViaMonadThrow e a]
-> (Otherwise :-> AssertViaMonadThrow e a)
-> AssertViaMonadThrow e a
forall (e :: * -> *) a.
CondExpFO e =>
AssertViaMonadThrow e a -> AssertViaMonadThrow e (Maybe a)
forall (e :: * -> *).
(forall a. e a -> e (Maybe a))
-> (forall a. [e Bool :-> e a] -> (Otherwise :-> e a) -> e a)
-> (forall a. HasCallStack => [e Bool :-> e a] -> e a)
-> CondExpFO e
partial_cases :: [AssertViaMonadThrow e Bool :-> AssertViaMonadThrow e a]
-> AssertViaMonadThrow e a
$cpartial_cases :: forall (e :: * -> *) a.
(CondExpFO e, HasCallStack) =>
[AssertViaMonadThrow e Bool :-> AssertViaMonadThrow e a]
-> AssertViaMonadThrow e a
cases :: [AssertViaMonadThrow e Bool :-> AssertViaMonadThrow e a]
-> (Otherwise :-> AssertViaMonadThrow e a)
-> AssertViaMonadThrow e a
$ccases :: forall (e :: * -> *) a.
CondExpFO e =>
[AssertViaMonadThrow e Bool :-> AssertViaMonadThrow e a]
-> (Otherwise :-> AssertViaMonadThrow e a)
-> AssertViaMonadThrow e a
just :: AssertViaMonadThrow e a -> AssertViaMonadThrow e (Maybe a)
$cjust :: forall (e :: * -> *) a.
CondExpFO e =>
AssertViaMonadThrow e a -> AssertViaMonadThrow e (Maybe a)
CondExpFO
             , CondExpFO (AssertViaMonadThrow e)
CondExpFO (AssertViaMonadThrow e)
-> (forall a b.
    DinoType a =>
    AssertViaMonadThrow e b
    -> (AssertViaMonadThrow e a -> AssertViaMonadThrow e b)
    -> AssertViaMonadThrow e (Maybe a)
    -> AssertViaMonadThrow e b)
-> CondExp (AssertViaMonadThrow e)
AssertViaMonadThrow e b
-> (AssertViaMonadThrow e a -> AssertViaMonadThrow e b)
-> AssertViaMonadThrow e (Maybe a)
-> AssertViaMonadThrow e b
forall a b.
DinoType a =>
AssertViaMonadThrow e b
-> (AssertViaMonadThrow e a -> AssertViaMonadThrow e b)
-> AssertViaMonadThrow e (Maybe a)
-> AssertViaMonadThrow e b
forall (e :: * -> *).
CondExp e =>
CondExpFO (AssertViaMonadThrow e)
forall (e :: * -> *) a b.
(CondExp e, DinoType a) =>
AssertViaMonadThrow e b
-> (AssertViaMonadThrow e a -> AssertViaMonadThrow e b)
-> AssertViaMonadThrow e (Maybe a)
-> AssertViaMonadThrow e b
forall (e :: * -> *).
CondExpFO e
-> (forall a b.
    DinoType a =>
    e b -> (e a -> e b) -> e (Maybe a) -> e b)
-> CondExp e
maybe :: AssertViaMonadThrow e b
-> (AssertViaMonadThrow e a -> AssertViaMonadThrow e b)
-> AssertViaMonadThrow e (Maybe a)
-> AssertViaMonadThrow e b
$cmaybe :: forall (e :: * -> *) a b.
(CondExp e, DinoType a) =>
AssertViaMonadThrow e b
-> (AssertViaMonadThrow e a -> AssertViaMonadThrow e b)
-> AssertViaMonadThrow e (Maybe a)
-> AssertViaMonadThrow e b
$cp1CondExp :: forall (e :: * -> *).
CondExp e =>
CondExpFO (AssertViaMonadThrow e)
CondExp
             , [AssertViaMonadThrow e a] -> AssertViaMonadThrow e [a]
AssertViaMonadThrow e a
-> AssertViaMonadThrow e a -> AssertViaMonadThrow e [a]
AssertViaMonadThrow e [a] -> AssertViaMonadThrow e (Maybe a)
AssertViaMonadThrow e [a]
-> AssertViaMonadThrow e [a] -> AssertViaMonadThrow e [a]
(forall a.
 Enum a =>
 AssertViaMonadThrow e a
 -> AssertViaMonadThrow e a -> AssertViaMonadThrow e [a])
-> (forall a.
    DinoType a =>
    [AssertViaMonadThrow e a] -> AssertViaMonadThrow e [a])
-> (forall a.
    AssertViaMonadThrow e [a] -> AssertViaMonadThrow e (Maybe a))
-> (forall a.
    AssertViaMonadThrow e [a]
    -> AssertViaMonadThrow e [a] -> AssertViaMonadThrow e [a])
-> ListExpFO (AssertViaMonadThrow e)
forall a.
Enum a =>
AssertViaMonadThrow e a
-> AssertViaMonadThrow e a -> AssertViaMonadThrow e [a]
forall a.
DinoType a =>
[AssertViaMonadThrow e a] -> AssertViaMonadThrow e [a]
forall a.
AssertViaMonadThrow e [a] -> AssertViaMonadThrow e (Maybe a)
forall a.
AssertViaMonadThrow e [a]
-> AssertViaMonadThrow e [a] -> AssertViaMonadThrow e [a]
forall (e :: * -> *) a.
(ListExpFO e, Enum a) =>
AssertViaMonadThrow e a
-> AssertViaMonadThrow e a -> AssertViaMonadThrow e [a]
forall (e :: * -> *) a.
(ListExpFO e, DinoType a) =>
[AssertViaMonadThrow e a] -> AssertViaMonadThrow e [a]
forall (e :: * -> *) a.
ListExpFO e =>
AssertViaMonadThrow e [a] -> AssertViaMonadThrow e (Maybe a)
forall (e :: * -> *) a.
ListExpFO e =>
AssertViaMonadThrow e [a]
-> AssertViaMonadThrow e [a] -> AssertViaMonadThrow e [a]
forall (e :: * -> *).
(forall a. Enum a => e a -> e a -> e [a])
-> (forall a. DinoType a => [e a] -> e [a])
-> (forall a. e [a] -> e (Maybe a))
-> (forall a. e [a] -> e [a] -> e [a])
-> ListExpFO e
append :: AssertViaMonadThrow e [a]
-> AssertViaMonadThrow e [a] -> AssertViaMonadThrow e [a]
$cappend :: forall (e :: * -> *) a.
ListExpFO e =>
AssertViaMonadThrow e [a]
-> AssertViaMonadThrow e [a] -> AssertViaMonadThrow e [a]
headE :: AssertViaMonadThrow e [a] -> AssertViaMonadThrow e (Maybe a)
$cheadE :: forall (e :: * -> *) a.
ListExpFO e =>
AssertViaMonadThrow e [a] -> AssertViaMonadThrow e (Maybe a)
list :: [AssertViaMonadThrow e a] -> AssertViaMonadThrow e [a]
$clist :: forall (e :: * -> *) a.
(ListExpFO e, DinoType a) =>
[AssertViaMonadThrow e a] -> AssertViaMonadThrow e [a]
range :: AssertViaMonadThrow e a
-> AssertViaMonadThrow e a -> AssertViaMonadThrow e [a]
$crange :: forall (e :: * -> *) a.
(ListExpFO e, Enum a) =>
AssertViaMonadThrow e a
-> AssertViaMonadThrow e a -> AssertViaMonadThrow e [a]
ListExpFO
             , ListExpFO (AssertViaMonadThrow e)
ListExpFO (AssertViaMonadThrow e)
-> (forall a b.
    DinoType a =>
    (AssertViaMonadThrow e a -> AssertViaMonadThrow e b)
    -> AssertViaMonadThrow e [a] -> AssertViaMonadThrow e [b])
-> (forall a.
    DinoType a =>
    (AssertViaMonadThrow e a -> AssertViaMonadThrow e Bool)
    -> AssertViaMonadThrow e [a] -> AssertViaMonadThrow e [a])
-> (forall a b.
    (DinoType a, DinoType b) =>
    (AssertViaMonadThrow e a
     -> AssertViaMonadThrow e b -> AssertViaMonadThrow e a)
    -> AssertViaMonadThrow e a
    -> AssertViaMonadThrow e [b]
    -> AssertViaMonadThrow e a)
-> ListExp (AssertViaMonadThrow e)
(AssertViaMonadThrow e a -> AssertViaMonadThrow e b)
-> AssertViaMonadThrow e [a] -> AssertViaMonadThrow e [b]
(AssertViaMonadThrow e a -> AssertViaMonadThrow e Bool)
-> AssertViaMonadThrow e [a] -> AssertViaMonadThrow e [a]
(AssertViaMonadThrow e a
 -> AssertViaMonadThrow e b -> AssertViaMonadThrow e a)
-> AssertViaMonadThrow e a
-> AssertViaMonadThrow e [b]
-> AssertViaMonadThrow e a
forall a.
DinoType a =>
(AssertViaMonadThrow e a -> AssertViaMonadThrow e Bool)
-> AssertViaMonadThrow e [a] -> AssertViaMonadThrow e [a]
forall a b.
(DinoType a, DinoType b) =>
(AssertViaMonadThrow e a
 -> AssertViaMonadThrow e b -> AssertViaMonadThrow e a)
-> AssertViaMonadThrow e a
-> AssertViaMonadThrow e [b]
-> AssertViaMonadThrow e a
forall a b.
DinoType a =>
(AssertViaMonadThrow e a -> AssertViaMonadThrow e b)
-> AssertViaMonadThrow e [a] -> AssertViaMonadThrow e [b]
forall (e :: * -> *).
ListExp e =>
ListExpFO (AssertViaMonadThrow e)
forall (e :: * -> *) a.
(ListExp e, DinoType a) =>
(AssertViaMonadThrow e a -> AssertViaMonadThrow e Bool)
-> AssertViaMonadThrow e [a] -> AssertViaMonadThrow e [a]
forall (e :: * -> *) a b.
(ListExp e, DinoType a, DinoType b) =>
(AssertViaMonadThrow e a
 -> AssertViaMonadThrow e b -> AssertViaMonadThrow e a)
-> AssertViaMonadThrow e a
-> AssertViaMonadThrow e [b]
-> AssertViaMonadThrow e a
forall (e :: * -> *) a b.
(ListExp e, DinoType a) =>
(AssertViaMonadThrow e a -> AssertViaMonadThrow e b)
-> AssertViaMonadThrow e [a] -> AssertViaMonadThrow e [b]
forall (e :: * -> *).
ListExpFO e
-> (forall a b. DinoType a => (e a -> e b) -> e [a] -> e [b])
-> (forall a. DinoType a => (e a -> e Bool) -> e [a] -> e [a])
-> (forall a b.
    (DinoType a, DinoType b) =>
    (e a -> e b -> e a) -> e a -> e [b] -> e a)
-> ListExp e
foldE :: (AssertViaMonadThrow e a
 -> AssertViaMonadThrow e b -> AssertViaMonadThrow e a)
-> AssertViaMonadThrow e a
-> AssertViaMonadThrow e [b]
-> AssertViaMonadThrow e a
$cfoldE :: forall (e :: * -> *) a b.
(ListExp e, DinoType a, DinoType b) =>
(AssertViaMonadThrow e a
 -> AssertViaMonadThrow e b -> AssertViaMonadThrow e a)
-> AssertViaMonadThrow e a
-> AssertViaMonadThrow e [b]
-> AssertViaMonadThrow e a
dropWhileE :: (AssertViaMonadThrow e a -> AssertViaMonadThrow e Bool)
-> AssertViaMonadThrow e [a] -> AssertViaMonadThrow e [a]
$cdropWhileE :: forall (e :: * -> *) a.
(ListExp e, DinoType a) =>
(AssertViaMonadThrow e a -> AssertViaMonadThrow e Bool)
-> AssertViaMonadThrow e [a] -> AssertViaMonadThrow e [a]
mapE :: (AssertViaMonadThrow e a -> AssertViaMonadThrow e b)
-> AssertViaMonadThrow e [a] -> AssertViaMonadThrow e [b]
$cmapE :: forall (e :: * -> *) a b.
(ListExp e, DinoType a) =>
(AssertViaMonadThrow e a -> AssertViaMonadThrow e b)
-> AssertViaMonadThrow e [a] -> AssertViaMonadThrow e [b]
$cp1ListExp :: forall (e :: * -> *).
ListExp e =>
ListExpFO (AssertViaMonadThrow e)
ListExp
             , AssertViaMonadThrow e a
-> AssertViaMonadThrow e b -> AssertViaMonadThrow e (a, b)
AssertViaMonadThrow e (a, b) -> AssertViaMonadThrow e a
AssertViaMonadThrow e (a, b) -> AssertViaMonadThrow e b
(forall a b.
 AssertViaMonadThrow e a
 -> AssertViaMonadThrow e b -> AssertViaMonadThrow e (a, b))
-> (forall a b.
    AssertViaMonadThrow e (a, b) -> AssertViaMonadThrow e a)
-> (forall a b.
    AssertViaMonadThrow e (a, b) -> AssertViaMonadThrow e b)
-> TupleExp (AssertViaMonadThrow e)
forall a b.
AssertViaMonadThrow e a
-> AssertViaMonadThrow e b -> AssertViaMonadThrow e (a, b)
forall a b. AssertViaMonadThrow e (a, b) -> AssertViaMonadThrow e a
forall a b. AssertViaMonadThrow e (a, b) -> AssertViaMonadThrow e b
forall (e :: * -> *) a b.
TupleExp e =>
AssertViaMonadThrow e a
-> AssertViaMonadThrow e b -> AssertViaMonadThrow e (a, b)
forall (e :: * -> *) a b.
TupleExp e =>
AssertViaMonadThrow e (a, b) -> AssertViaMonadThrow e a
forall (e :: * -> *) a b.
TupleExp e =>
AssertViaMonadThrow e (a, b) -> AssertViaMonadThrow e b
forall (e :: * -> *).
(forall a b. e a -> e b -> e (a, b))
-> (forall a b. e (a, b) -> e a)
-> (forall a b. e (a, b) -> e b)
-> TupleExp e
sndE :: AssertViaMonadThrow e (a, b) -> AssertViaMonadThrow e b
$csndE :: forall (e :: * -> *) a b.
TupleExp e =>
AssertViaMonadThrow e (a, b) -> AssertViaMonadThrow e b
fstE :: AssertViaMonadThrow e (a, b) -> AssertViaMonadThrow e a
$cfstE :: forall (e :: * -> *) a b.
TupleExp e =>
AssertViaMonadThrow e (a, b) -> AssertViaMonadThrow e a
pair :: AssertViaMonadThrow e a
-> AssertViaMonadThrow e b -> AssertViaMonadThrow e (a, b)
$cpair :: forall (e :: * -> *) a b.
TupleExp e =>
AssertViaMonadThrow e a
-> AssertViaMonadThrow e b -> AssertViaMonadThrow e (a, b)
TupleExp
             , Text
-> AssertViaMonadThrow e a
-> (AssertViaMonadThrow e a -> AssertViaMonadThrow e b)
-> AssertViaMonadThrow e b
(forall a b.
 DinoType a =>
 Text
 -> AssertViaMonadThrow e a
 -> (AssertViaMonadThrow e a -> AssertViaMonadThrow e b)
 -> AssertViaMonadThrow e b)
-> LetExp (AssertViaMonadThrow e)
forall a b.
DinoType a =>
Text
-> AssertViaMonadThrow e a
-> (AssertViaMonadThrow e a -> AssertViaMonadThrow e b)
-> AssertViaMonadThrow e b
forall (e :: * -> *) a b.
(LetExp e, DinoType a) =>
Text
-> AssertViaMonadThrow e a
-> (AssertViaMonadThrow e a -> AssertViaMonadThrow e b)
-> AssertViaMonadThrow e b
forall (e :: * -> *).
(forall a b. DinoType a => Text -> e a -> (e a -> e b) -> e b)
-> LetExp e
letE :: Text
-> AssertViaMonadThrow e a
-> (AssertViaMonadThrow e a -> AssertViaMonadThrow e b)
-> AssertViaMonadThrow e b
$cletE :: forall (e :: * -> *) a b.
(LetExp e, DinoType a) =>
Text
-> AssertViaMonadThrow e a
-> (AssertViaMonadThrow e a -> AssertViaMonadThrow e b)
-> AssertViaMonadThrow e b
LetExp
             , proxy f -> AssertViaMonadThrow e r -> AssertViaMonadThrow e a
(forall (f :: Symbol) r a (proxy :: Symbol -> *).
 (KnownSymbol f, HasField f r a, DinoType a) =>
 proxy f -> AssertViaMonadThrow e r -> AssertViaMonadThrow e a)
-> FieldExp (AssertViaMonadThrow e)
forall (f :: Symbol) r a (proxy :: Symbol -> *).
(KnownSymbol f, HasField f r a, DinoType a) =>
proxy f -> AssertViaMonadThrow e r -> AssertViaMonadThrow e a
forall (e :: * -> *) (f :: Symbol) r a (proxy :: Symbol -> *).
(FieldExp e, KnownSymbol f, HasField f r a, DinoType a) =>
proxy f -> AssertViaMonadThrow e r -> AssertViaMonadThrow e a
forall (e :: * -> *).
(forall (f :: Symbol) r a (proxy :: Symbol -> *).
 (KnownSymbol f, HasField f r a, DinoType a) =>
 proxy f -> e r -> e a)
-> FieldExp e
getField :: proxy f -> AssertViaMonadThrow e r -> AssertViaMonadThrow e a
$cgetField :: forall (e :: * -> *) (f :: Symbol) r a (proxy :: Symbol -> *).
(FieldExp e, KnownSymbol f, HasField f r a, DinoType a) =>
proxy f -> AssertViaMonadThrow e r -> AssertViaMonadThrow e a
FieldExp
             , AnnExp ann
             )

-- | Throws 'InvalidAssertion' in the underlying monad
instance MonadThrow e => AssertExp (AssertViaMonadThrow e) where
  assert :: Text
-> AssertViaMonadThrow e Bool
-> AssertViaMonadThrow e a
-> AssertViaMonadThrow e a
assert Text
lab AssertViaMonadThrow e Bool
cond AssertViaMonadThrow e a
a = do
    Bool
c <- AssertViaMonadThrow e Bool
cond
    Bool -> AssertViaMonadThrow e () -> AssertViaMonadThrow e ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless Bool
c (AssertViaMonadThrow e () -> AssertViaMonadThrow e ())
-> AssertViaMonadThrow e () -> AssertViaMonadThrow e ()
forall a b. (a -> b) -> a -> b
$ InvalidAssertion -> AssertViaMonadThrow e ()
forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM (InvalidAssertion -> AssertViaMonadThrow e ())
-> InvalidAssertion -> AssertViaMonadThrow e ()
forall a b. (a -> b) -> a -> b
$ Text -> InvalidAssertion
InvalidCondition Text
lab
    AssertViaMonadThrow e a
a

  assertEq :: Text
-> AssertViaMonadThrow e a
-> AssertViaMonadThrow e a
-> AssertViaMonadThrow e a
assertEq Text
lab AssertViaMonadThrow e a
ref AssertViaMonadThrow e a
act = do
    a
r <- AssertViaMonadThrow e a
ref
    a
a <- AssertViaMonadThrow e a
act
    Bool -> AssertViaMonadThrow e () -> AssertViaMonadThrow e ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (a
r a -> a -> Bool
forall a. Eq a => a -> a -> Bool
Prelude.== a
a) (AssertViaMonadThrow e () -> AssertViaMonadThrow e ())
-> AssertViaMonadThrow e () -> AssertViaMonadThrow e ()
forall a b. (a -> b) -> a -> b
$
      InvalidAssertion -> AssertViaMonadThrow e ()
forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM (InvalidAssertion -> AssertViaMonadThrow e ())
-> InvalidAssertion -> AssertViaMonadThrow e ()
forall a b. (a -> b) -> a -> b
$ Text -> Text -> Text -> InvalidAssertion
NotEqual Text
lab (String -> Text
Text.pack (String -> Text) -> String -> Text
forall a b. (a -> b) -> a -> b
$ a -> String
forall a. Show a => a -> String
show a
r) (String -> Text
Text.pack (String -> Text) -> String -> Text
forall a b. (a -> b) -> a -> b
$ a -> String
forall a. Show a => a -> String
show a
a)
    a -> AssertViaMonadThrow e a
forall (m :: * -> *) a. Monad m => a -> m a
return a
a

data Assertion e where
  Assert   :: e Bool -> Assertion e
  AssertEq :: (Eq a, Show a) => e a -> e a -> Assertion e

-- | Collect all assertions in an expression
--
-- Note that the wrapped interpretation @e@ must have instances of intensional
-- classes in order for 'CollectAssertions' to derive instances of HOS classes.
-- In order for the wrapped interpretation to do monadic evaluation, use the
-- wrapper 'EvalEnv' to obtain the necessary intensional instances.
newtype CollectAssertions e a = CollectAssertions
  { CollectAssertions e a
-> Intensional (e :×: Fold [(Text, Assertion e)]) a
unCollectAssertions :: (Intensional (e :×: Fold [(Text, Assertion e)])) a
  } deriving ( a -> CollectAssertions e a
(forall a. DinoType a => a -> CollectAssertions e a)
-> ConstExp (CollectAssertions e)
forall a. DinoType a => a -> CollectAssertions e a
forall (e :: * -> *) a.
(ConstExp e, DinoType a) =>
a -> CollectAssertions e a
forall (e :: * -> *).
(forall a. DinoType a => a -> e a) -> ConstExp e
lit :: a -> CollectAssertions e a
$clit :: forall (e :: * -> *) a.
(ConstExp e, DinoType a) =>
a -> CollectAssertions e a
ConstExp
             , Int -> CollectAssertions e a -> CollectAssertions e a
CollectAssertions e a
-> CollectAssertions e a -> CollectAssertions e a
CollectAssertions e a
-> CollectAssertions e a -> CollectAssertions e a
CollectAssertions e a
-> CollectAssertions e a -> CollectAssertions e a
CollectAssertions e a -> CollectAssertions e a
CollectAssertions e a -> CollectAssertions e a
CollectAssertions e a -> CollectAssertions e b
CollectAssertions e a -> CollectAssertions e b
CollectAssertions e a -> CollectAssertions e b
(forall a.
 Num a =>
 CollectAssertions e a
 -> CollectAssertions e a -> CollectAssertions e a)
-> (forall a.
    Num a =>
    CollectAssertions e a
    -> CollectAssertions e a -> CollectAssertions e a)
-> (forall a.
    Num a =>
    CollectAssertions e a
    -> CollectAssertions e a -> CollectAssertions e a)
-> (forall a.
    Num a =>
    CollectAssertions e a -> CollectAssertions e a)
-> (forall a.
    Num a =>
    CollectAssertions e a -> CollectAssertions e a)
-> (forall a b.
    (Integral a, DinoType b, Num b) =>
    CollectAssertions e a -> CollectAssertions e b)
-> (forall a b.
    (RealFrac a, DinoType b, Integral b) =>
    CollectAssertions e a -> CollectAssertions e b)
-> (forall a b.
    (RealFrac a, DinoType b, Integral b) =>
    CollectAssertions e a -> CollectAssertions e b)
-> (forall a.
    RealFrac a =>
    Int -> CollectAssertions e a -> CollectAssertions e a)
-> NumExp (CollectAssertions e)
forall a. Num a => CollectAssertions e a -> CollectAssertions e a
forall a.
Num a =>
CollectAssertions e a
-> CollectAssertions e a -> CollectAssertions e a
forall a.
RealFrac a =>
Int -> CollectAssertions e a -> CollectAssertions e a
forall a b.
(Integral a, DinoType b, Num b) =>
CollectAssertions e a -> CollectAssertions e b
forall a b.
(RealFrac a, DinoType b, Integral b) =>
CollectAssertions e a -> CollectAssertions e b
forall (e :: * -> *) a.
(NumExp e, Num a) =>
CollectAssertions e a -> CollectAssertions e a
forall (e :: * -> *) a.
(NumExp e, Num a) =>
CollectAssertions e a
-> CollectAssertions e a -> CollectAssertions e a
forall (e :: * -> *) a.
(NumExp e, RealFrac a) =>
Int -> CollectAssertions e a -> CollectAssertions e a
forall (e :: * -> *) a b.
(NumExp e, Integral a, DinoType b, Num b) =>
CollectAssertions e a -> CollectAssertions e b
forall (e :: * -> *) a b.
(NumExp e, RealFrac a, DinoType b, Integral b) =>
CollectAssertions e a -> CollectAssertions e b
forall (e :: * -> *).
(forall a. Num a => e a -> e a -> e a)
-> (forall a. Num a => e a -> e a -> e a)
-> (forall a. Num a => e a -> e a -> e a)
-> (forall a. Num a => e a -> e a)
-> (forall a. Num a => e a -> e a)
-> (forall a b. (Integral a, DinoType b, Num b) => e a -> e b)
-> (forall a b. (RealFrac a, DinoType b, Integral b) => e a -> e b)
-> (forall a b. (RealFrac a, DinoType b, Integral b) => e a -> e b)
-> (forall a. RealFrac a => Int -> e a -> e a)
-> NumExp e
roundN :: Int -> CollectAssertions e a -> CollectAssertions e a
$croundN :: forall (e :: * -> *) a.
(NumExp e, RealFrac a) =>
Int -> CollectAssertions e a -> CollectAssertions e a
truncate :: CollectAssertions e a -> CollectAssertions e b
$ctruncate :: forall (e :: * -> *) a b.
(NumExp e, RealFrac a, DinoType b, Integral b) =>
CollectAssertions e a -> CollectAssertions e b
floor :: CollectAssertions e a -> CollectAssertions e b
$cfloor :: forall (e :: * -> *) a b.
(NumExp e, RealFrac a, DinoType b, Integral b) =>
CollectAssertions e a -> CollectAssertions e b
fromIntegral :: CollectAssertions e a -> CollectAssertions e b
$cfromIntegral :: forall (e :: * -> *) a b.
(NumExp e, Integral a, DinoType b, Num b) =>
CollectAssertions e a -> CollectAssertions e b
signE :: CollectAssertions e a -> CollectAssertions e a
$csignE :: forall (e :: * -> *) a.
(NumExp e, Num a) =>
CollectAssertions e a -> CollectAssertions e a
absE :: CollectAssertions e a -> CollectAssertions e a
$cabsE :: forall (e :: * -> *) a.
(NumExp e, Num a) =>
CollectAssertions e a -> CollectAssertions e a
mul :: CollectAssertions e a
-> CollectAssertions e a -> CollectAssertions e a
$cmul :: forall (e :: * -> *) a.
(NumExp e, Num a) =>
CollectAssertions e a
-> CollectAssertions e a -> CollectAssertions e a
sub :: CollectAssertions e a
-> CollectAssertions e a -> CollectAssertions e a
$csub :: forall (e :: * -> *) a.
(NumExp e, Num a) =>
CollectAssertions e a
-> CollectAssertions e a -> CollectAssertions e a
add :: CollectAssertions e a
-> CollectAssertions e a -> CollectAssertions e a
$cadd :: forall (e :: * -> *) a.
(NumExp e, Num a) =>
CollectAssertions e a
-> CollectAssertions e a -> CollectAssertions e a
NumExp
             , CollectAssertions e a
-> CollectAssertions e a -> CollectAssertions e a
(forall a.
 (Fractional a, Eq a) =>
 CollectAssertions e a
 -> CollectAssertions e a -> CollectAssertions e a)
-> FracExp (CollectAssertions e)
forall a.
(Fractional a, Eq a) =>
CollectAssertions e a
-> CollectAssertions e a -> CollectAssertions e a
forall (e :: * -> *) a.
(FracExp e, Fractional a, Eq a) =>
CollectAssertions e a
-> CollectAssertions e a -> CollectAssertions e a
forall (e :: * -> *).
(forall a. (Fractional a, Eq a) => e a -> e a -> e a) -> FracExp e
fdiv :: CollectAssertions e a
-> CollectAssertions e a -> CollectAssertions e a
$cfdiv :: forall (e :: * -> *) a.
(FracExp e, Fractional a, Eq a) =>
CollectAssertions e a
-> CollectAssertions e a -> CollectAssertions e a
FracExp
             , CollectAssertions e Bool -> CollectAssertions e Bool
CollectAssertions e Bool
-> CollectAssertions e Bool -> CollectAssertions e Bool
(CollectAssertions e Bool -> CollectAssertions e Bool)
-> (CollectAssertions e Bool
    -> CollectAssertions e Bool -> CollectAssertions e Bool)
-> (CollectAssertions e Bool
    -> CollectAssertions e Bool -> CollectAssertions e Bool)
-> (CollectAssertions e Bool
    -> CollectAssertions e Bool -> CollectAssertions e Bool)
-> LogicExp (CollectAssertions e)
forall (e :: * -> *).
LogicExp e =>
CollectAssertions e Bool -> CollectAssertions e Bool
forall (e :: * -> *).
LogicExp e =>
CollectAssertions e Bool
-> CollectAssertions e Bool -> CollectAssertions e Bool
forall (e :: * -> *).
(e Bool -> e Bool)
-> (e Bool -> e Bool -> e Bool)
-> (e Bool -> e Bool -> e Bool)
-> (e Bool -> e Bool -> e Bool)
-> LogicExp e
xor :: CollectAssertions e Bool
-> CollectAssertions e Bool -> CollectAssertions e Bool
$cxor :: forall (e :: * -> *).
LogicExp e =>
CollectAssertions e Bool
-> CollectAssertions e Bool -> CollectAssertions e Bool
disj :: CollectAssertions e Bool
-> CollectAssertions e Bool -> CollectAssertions e Bool
$cdisj :: forall (e :: * -> *).
LogicExp e =>
CollectAssertions e Bool
-> CollectAssertions e Bool -> CollectAssertions e Bool
conj :: CollectAssertions e Bool
-> CollectAssertions e Bool -> CollectAssertions e Bool
$cconj :: forall (e :: * -> *).
LogicExp e =>
CollectAssertions e Bool
-> CollectAssertions e Bool -> CollectAssertions e Bool
not :: CollectAssertions e Bool -> CollectAssertions e Bool
$cnot :: forall (e :: * -> *).
LogicExp e =>
CollectAssertions e Bool -> CollectAssertions e Bool
LogicExp
             , CollectAssertions e a
-> CollectAssertions e a -> CollectAssertions e Bool
CollectAssertions e a
-> CollectAssertions e a -> CollectAssertions e Bool
CollectAssertions e a
-> CollectAssertions e a -> CollectAssertions e Bool
CollectAssertions e a
-> CollectAssertions e a -> CollectAssertions e Bool
CollectAssertions e a
-> CollectAssertions e a -> CollectAssertions e Bool
CollectAssertions e a
-> CollectAssertions e a -> CollectAssertions e Bool
CollectAssertions e a
-> CollectAssertions e a -> CollectAssertions e a
CollectAssertions e a
-> CollectAssertions e a -> CollectAssertions e a
(forall a.
 Eq a =>
 CollectAssertions e a
 -> CollectAssertions e a -> CollectAssertions e Bool)
-> (forall a.
    Eq a =>
    CollectAssertions e a
    -> CollectAssertions e a -> CollectAssertions e Bool)
-> (forall a.
    Ord a =>
    CollectAssertions e a
    -> CollectAssertions e a -> CollectAssertions e Bool)
-> (forall a.
    Ord a =>
    CollectAssertions e a
    -> CollectAssertions e a -> CollectAssertions e Bool)
-> (forall a.
    Ord a =>
    CollectAssertions e a
    -> CollectAssertions e a -> CollectAssertions e Bool)
-> (forall a.
    Ord a =>
    CollectAssertions e a
    -> CollectAssertions e a -> CollectAssertions e Bool)
-> (forall a.
    Ord a =>
    CollectAssertions e a
    -> CollectAssertions e a -> CollectAssertions e a)
-> (forall a.
    Ord a =>
    CollectAssertions e a
    -> CollectAssertions e a -> CollectAssertions e a)
-> CompareExp (CollectAssertions e)
forall a.
Eq a =>
CollectAssertions e a
-> CollectAssertions e a -> CollectAssertions e Bool
forall a.
Ord a =>
CollectAssertions e a
-> CollectAssertions e a -> CollectAssertions e a
forall a.
Ord a =>
CollectAssertions e a
-> CollectAssertions e a -> CollectAssertions e Bool
forall (e :: * -> *) a.
(CompareExp e, Eq a) =>
CollectAssertions e a
-> CollectAssertions e a -> CollectAssertions e Bool
forall (e :: * -> *) a.
(CompareExp e, Ord a) =>
CollectAssertions e a
-> CollectAssertions e a -> CollectAssertions e a
forall (e :: * -> *) a.
(CompareExp e, Ord a) =>
CollectAssertions e a
-> CollectAssertions e a -> CollectAssertions e Bool
forall (e :: * -> *).
(forall a. Eq a => e a -> e a -> e Bool)
-> (forall a. Eq a => e a -> e a -> e Bool)
-> (forall a. Ord a => e a -> e a -> e Bool)
-> (forall a. Ord a => e a -> e a -> e Bool)
-> (forall a. Ord a => e a -> e a -> e Bool)
-> (forall a. Ord a => e a -> e a -> e Bool)
-> (forall a. Ord a => e a -> e a -> e a)
-> (forall a. Ord a => e a -> e a -> e a)
-> CompareExp e
max :: CollectAssertions e a
-> CollectAssertions e a -> CollectAssertions e a
$cmax :: forall (e :: * -> *) a.
(CompareExp e, Ord a) =>
CollectAssertions e a
-> CollectAssertions e a -> CollectAssertions e a
min :: CollectAssertions e a
-> CollectAssertions e a -> CollectAssertions e a
$cmin :: forall (e :: * -> *) a.
(CompareExp e, Ord a) =>
CollectAssertions e a
-> CollectAssertions e a -> CollectAssertions e a
gte :: CollectAssertions e a
-> CollectAssertions e a -> CollectAssertions e Bool
$cgte :: forall (e :: * -> *) a.
(CompareExp e, Ord a) =>
CollectAssertions e a
-> CollectAssertions e a -> CollectAssertions e Bool
lte :: CollectAssertions e a
-> CollectAssertions e a -> CollectAssertions e Bool
$clte :: forall (e :: * -> *) a.
(CompareExp e, Ord a) =>
CollectAssertions e a
-> CollectAssertions e a -> CollectAssertions e Bool
gt :: CollectAssertions e a
-> CollectAssertions e a -> CollectAssertions e Bool
$cgt :: forall (e :: * -> *) a.
(CompareExp e, Ord a) =>
CollectAssertions e a
-> CollectAssertions e a -> CollectAssertions e Bool
lt :: CollectAssertions e a
-> CollectAssertions e a -> CollectAssertions e Bool
$clt :: forall (e :: * -> *) a.
(CompareExp e, Ord a) =>
CollectAssertions e a
-> CollectAssertions e a -> CollectAssertions e Bool
neq :: CollectAssertions e a
-> CollectAssertions e a -> CollectAssertions e Bool
$cneq :: forall (e :: * -> *) a.
(CompareExp e, Eq a) =>
CollectAssertions e a
-> CollectAssertions e a -> CollectAssertions e Bool
eq :: CollectAssertions e a
-> CollectAssertions e a -> CollectAssertions e Bool
$ceq :: forall (e :: * -> *) a.
(CompareExp e, Eq a) =>
CollectAssertions e a
-> CollectAssertions e a -> CollectAssertions e Bool
CompareExp
             , [CollectAssertions e Bool :-> CollectAssertions e a]
-> (Otherwise :-> CollectAssertions e a) -> CollectAssertions e a
[CollectAssertions e Bool :-> CollectAssertions e a]
-> CollectAssertions e a
CollectAssertions e a -> CollectAssertions e (Maybe a)
(forall a. CollectAssertions e a -> CollectAssertions e (Maybe a))
-> (forall a.
    [CollectAssertions e Bool :-> CollectAssertions e a]
    -> (Otherwise :-> CollectAssertions e a) -> CollectAssertions e a)
-> (forall a.
    HasCallStack =>
    [CollectAssertions e Bool :-> CollectAssertions e a]
    -> CollectAssertions e a)
-> CondExpFO (CollectAssertions e)
forall a.
HasCallStack =>
[CollectAssertions e Bool :-> CollectAssertions e a]
-> CollectAssertions e a
forall a.
[CollectAssertions e Bool :-> CollectAssertions e a]
-> (Otherwise :-> CollectAssertions e a) -> CollectAssertions e a
forall a. CollectAssertions e a -> CollectAssertions e (Maybe a)
forall (e :: * -> *) a.
(CondExpFO e, HasCallStack) =>
[CollectAssertions e Bool :-> CollectAssertions e a]
-> CollectAssertions e a
forall (e :: * -> *) a.
CondExpFO e =>
[CollectAssertions e Bool :-> CollectAssertions e a]
-> (Otherwise :-> CollectAssertions e a) -> CollectAssertions e a
forall (e :: * -> *) a.
CondExpFO e =>
CollectAssertions e a -> CollectAssertions e (Maybe a)
forall (e :: * -> *).
(forall a. e a -> e (Maybe a))
-> (forall a. [e Bool :-> e a] -> (Otherwise :-> e a) -> e a)
-> (forall a. HasCallStack => [e Bool :-> e a] -> e a)
-> CondExpFO e
partial_cases :: [CollectAssertions e Bool :-> CollectAssertions e a]
-> CollectAssertions e a
$cpartial_cases :: forall (e :: * -> *) a.
(CondExpFO e, HasCallStack) =>
[CollectAssertions e Bool :-> CollectAssertions e a]
-> CollectAssertions e a
cases :: [CollectAssertions e Bool :-> CollectAssertions e a]
-> (Otherwise :-> CollectAssertions e a) -> CollectAssertions e a
$ccases :: forall (e :: * -> *) a.
CondExpFO e =>
[CollectAssertions e Bool :-> CollectAssertions e a]
-> (Otherwise :-> CollectAssertions e a) -> CollectAssertions e a
just :: CollectAssertions e a -> CollectAssertions e (Maybe a)
$cjust :: forall (e :: * -> *) a.
CondExpFO e =>
CollectAssertions e a -> CollectAssertions e (Maybe a)
CondExpFO
             , CondExpFO (CollectAssertions e)
CondExpFO (CollectAssertions e)
-> (forall a b.
    DinoType a =>
    CollectAssertions e b
    -> (CollectAssertions e a -> CollectAssertions e b)
    -> CollectAssertions e (Maybe a)
    -> CollectAssertions e b)
-> CondExp (CollectAssertions e)
CollectAssertions e b
-> (CollectAssertions e a -> CollectAssertions e b)
-> CollectAssertions e (Maybe a)
-> CollectAssertions e b
forall a b.
DinoType a =>
CollectAssertions e b
-> (CollectAssertions e a -> CollectAssertions e b)
-> CollectAssertions e (Maybe a)
-> CollectAssertions e b
forall (e :: * -> *).
(CondExpFO e, VarExp e, CondIntensional e) =>
CondExpFO (CollectAssertions e)
forall (e :: * -> *) a b.
(CondExpFO e, VarExp e, CondIntensional e, DinoType a) =>
CollectAssertions e b
-> (CollectAssertions e a -> CollectAssertions e b)
-> CollectAssertions e (Maybe a)
-> CollectAssertions e b
forall (e :: * -> *).
CondExpFO e
-> (forall a b.
    DinoType a =>
    e b -> (e a -> e b) -> e (Maybe a) -> e b)
-> CondExp e
maybe :: CollectAssertions e b
-> (CollectAssertions e a -> CollectAssertions e b)
-> CollectAssertions e (Maybe a)
-> CollectAssertions e b
$cmaybe :: forall (e :: * -> *) a b.
(CondExpFO e, VarExp e, CondIntensional e, DinoType a) =>
CollectAssertions e b
-> (CollectAssertions e a -> CollectAssertions e b)
-> CollectAssertions e (Maybe a)
-> CollectAssertions e b
$cp1CondExp :: forall (e :: * -> *).
(CondExpFO e, VarExp e, CondIntensional e) =>
CondExpFO (CollectAssertions e)
CondExp
             , [CollectAssertions e a] -> CollectAssertions e [a]
CollectAssertions e a
-> CollectAssertions e a -> CollectAssertions e [a]
CollectAssertions e [a] -> CollectAssertions e (Maybe a)
CollectAssertions e [a]
-> CollectAssertions e [a] -> CollectAssertions e [a]
(forall a.
 Enum a =>
 CollectAssertions e a
 -> CollectAssertions e a -> CollectAssertions e [a])
-> (forall a.
    DinoType a =>
    [CollectAssertions e a] -> CollectAssertions e [a])
-> (forall a.
    CollectAssertions e [a] -> CollectAssertions e (Maybe a))
-> (forall a.
    CollectAssertions e [a]
    -> CollectAssertions e [a] -> CollectAssertions e [a])
-> ListExpFO (CollectAssertions e)
forall a.
Enum a =>
CollectAssertions e a
-> CollectAssertions e a -> CollectAssertions e [a]
forall a.
DinoType a =>
[CollectAssertions e a] -> CollectAssertions e [a]
forall a. CollectAssertions e [a] -> CollectAssertions e (Maybe a)
forall a.
CollectAssertions e [a]
-> CollectAssertions e [a] -> CollectAssertions e [a]
forall (e :: * -> *) a.
(ListExpFO e, Enum a) =>
CollectAssertions e a
-> CollectAssertions e a -> CollectAssertions e [a]
forall (e :: * -> *) a.
(ListExpFO e, DinoType a) =>
[CollectAssertions e a] -> CollectAssertions e [a]
forall (e :: * -> *) a.
ListExpFO e =>
CollectAssertions e [a] -> CollectAssertions e (Maybe a)
forall (e :: * -> *) a.
ListExpFO e =>
CollectAssertions e [a]
-> CollectAssertions e [a] -> CollectAssertions e [a]
forall (e :: * -> *).
(forall a. Enum a => e a -> e a -> e [a])
-> (forall a. DinoType a => [e a] -> e [a])
-> (forall a. e [a] -> e (Maybe a))
-> (forall a. e [a] -> e [a] -> e [a])
-> ListExpFO e
append :: CollectAssertions e [a]
-> CollectAssertions e [a] -> CollectAssertions e [a]
$cappend :: forall (e :: * -> *) a.
ListExpFO e =>
CollectAssertions e [a]
-> CollectAssertions e [a] -> CollectAssertions e [a]
headE :: CollectAssertions e [a] -> CollectAssertions e (Maybe a)
$cheadE :: forall (e :: * -> *) a.
ListExpFO e =>
CollectAssertions e [a] -> CollectAssertions e (Maybe a)
list :: [CollectAssertions e a] -> CollectAssertions e [a]
$clist :: forall (e :: * -> *) a.
(ListExpFO e, DinoType a) =>
[CollectAssertions e a] -> CollectAssertions e [a]
range :: CollectAssertions e a
-> CollectAssertions e a -> CollectAssertions e [a]
$crange :: forall (e :: * -> *) a.
(ListExpFO e, Enum a) =>
CollectAssertions e a
-> CollectAssertions e a -> CollectAssertions e [a]
ListExpFO
             , ListExpFO (CollectAssertions e)
ListExpFO (CollectAssertions e)
-> (forall a b.
    DinoType a =>
    (CollectAssertions e a -> CollectAssertions e b)
    -> CollectAssertions e [a] -> CollectAssertions e [b])
-> (forall a.
    DinoType a =>
    (CollectAssertions e a -> CollectAssertions e Bool)
    -> CollectAssertions e [a] -> CollectAssertions e [a])
-> (forall a b.
    (DinoType a, DinoType b) =>
    (CollectAssertions e a
     -> CollectAssertions e b -> CollectAssertions e a)
    -> CollectAssertions e a
    -> CollectAssertions e [b]
    -> CollectAssertions e a)
-> ListExp (CollectAssertions e)
(CollectAssertions e a -> CollectAssertions e b)
-> CollectAssertions e [a] -> CollectAssertions e [b]
(CollectAssertions e a -> CollectAssertions e Bool)
-> CollectAssertions e [a] -> CollectAssertions e [a]
(CollectAssertions e a
 -> CollectAssertions e b -> CollectAssertions e a)
-> CollectAssertions e a
-> CollectAssertions e [b]
-> CollectAssertions e a
forall a.
DinoType a =>
(CollectAssertions e a -> CollectAssertions e Bool)
-> CollectAssertions e [a] -> CollectAssertions e [a]
forall a b.
(DinoType a, DinoType b) =>
(CollectAssertions e a
 -> CollectAssertions e b -> CollectAssertions e a)
-> CollectAssertions e a
-> CollectAssertions e [b]
-> CollectAssertions e a
forall a b.
DinoType a =>
(CollectAssertions e a -> CollectAssertions e b)
-> CollectAssertions e [a] -> CollectAssertions e [b]
forall (e :: * -> *).
(ListExpFO e, VarExp e, ListIntensional e) =>
ListExpFO (CollectAssertions e)
forall (e :: * -> *) a.
(ListExpFO e, VarExp e, ListIntensional e, DinoType a) =>
(CollectAssertions e a -> CollectAssertions e Bool)
-> CollectAssertions e [a] -> CollectAssertions e [a]
forall (e :: * -> *) a b.
(ListExpFO e, VarExp e, ListIntensional e, DinoType a,
 DinoType b) =>
(CollectAssertions e a
 -> CollectAssertions e b -> CollectAssertions e a)
-> CollectAssertions e a
-> CollectAssertions e [b]
-> CollectAssertions e a
forall (e :: * -> *) a b.
(ListExpFO e, VarExp e, ListIntensional e, DinoType a) =>
(CollectAssertions e a -> CollectAssertions e b)
-> CollectAssertions e [a] -> CollectAssertions e [b]
forall (e :: * -> *).
ListExpFO e
-> (forall a b. DinoType a => (e a -> e b) -> e [a] -> e [b])
-> (forall a. DinoType a => (e a -> e Bool) -> e [a] -> e [a])
-> (forall a b.
    (DinoType a, DinoType b) =>
    (e a -> e b -> e a) -> e a -> e [b] -> e a)
-> ListExp e
foldE :: (CollectAssertions e a
 -> CollectAssertions e b -> CollectAssertions e a)
-> CollectAssertions e a
-> CollectAssertions e [b]
-> CollectAssertions e a
$cfoldE :: forall (e :: * -> *) a b.
(ListExpFO e, VarExp e, ListIntensional e, DinoType a,
 DinoType b) =>
(CollectAssertions e a
 -> CollectAssertions e b -> CollectAssertions e a)
-> CollectAssertions e a
-> CollectAssertions e [b]
-> CollectAssertions e a
dropWhileE :: (CollectAssertions e a -> CollectAssertions e Bool)
-> CollectAssertions e [a] -> CollectAssertions e [a]
$cdropWhileE :: forall (e :: * -> *) a.
(ListExpFO e, VarExp e, ListIntensional e, DinoType a) =>
(CollectAssertions e a -> CollectAssertions e Bool)
-> CollectAssertions e [a] -> CollectAssertions e [a]
mapE :: (CollectAssertions e a -> CollectAssertions e b)
-> CollectAssertions e [a] -> CollectAssertions e [b]
$cmapE :: forall (e :: * -> *) a b.
(ListExpFO e, VarExp e, ListIntensional e, DinoType a) =>
(CollectAssertions e a -> CollectAssertions e b)
-> CollectAssertions e [a] -> CollectAssertions e [b]
$cp1ListExp :: forall (e :: * -> *).
(ListExpFO e, VarExp e, ListIntensional e) =>
ListExpFO (CollectAssertions e)
ListExp
             , CollectAssertions e a
-> CollectAssertions e b -> CollectAssertions e (a, b)
CollectAssertions e (a, b) -> CollectAssertions e a
CollectAssertions e (a, b) -> CollectAssertions e b
(forall a b.
 CollectAssertions e a
 -> CollectAssertions e b -> CollectAssertions e (a, b))
-> (forall a b.
    CollectAssertions e (a, b) -> CollectAssertions e a)
-> (forall a b.
    CollectAssertions e (a, b) -> CollectAssertions e b)
-> TupleExp (CollectAssertions e)
forall a b.
CollectAssertions e a
-> CollectAssertions e b -> CollectAssertions e (a, b)
forall a b. CollectAssertions e (a, b) -> CollectAssertions e a
forall a b. CollectAssertions e (a, b) -> CollectAssertions e b
forall (e :: * -> *) a b.
TupleExp e =>
CollectAssertions e a
-> CollectAssertions e b -> CollectAssertions e (a, b)
forall (e :: * -> *) a b.
TupleExp e =>
CollectAssertions e (a, b) -> CollectAssertions e a
forall (e :: * -> *) a b.
TupleExp e =>
CollectAssertions e (a, b) -> CollectAssertions e b
forall (e :: * -> *).
(forall a b. e a -> e b -> e (a, b))
-> (forall a b. e (a, b) -> e a)
-> (forall a b. e (a, b) -> e b)
-> TupleExp e
sndE :: CollectAssertions e (a, b) -> CollectAssertions e b
$csndE :: forall (e :: * -> *) a b.
TupleExp e =>
CollectAssertions e (a, b) -> CollectAssertions e b
fstE :: CollectAssertions e (a, b) -> CollectAssertions e a
$cfstE :: forall (e :: * -> *) a b.
TupleExp e =>
CollectAssertions e (a, b) -> CollectAssertions e a
pair :: CollectAssertions e a
-> CollectAssertions e b -> CollectAssertions e (a, b)
$cpair :: forall (e :: * -> *) a b.
TupleExp e =>
CollectAssertions e a
-> CollectAssertions e b -> CollectAssertions e (a, b)
TupleExp
             , Text
-> CollectAssertions e a
-> (CollectAssertions e a -> CollectAssertions e b)
-> CollectAssertions e b
(forall a b.
 DinoType a =>
 Text
 -> CollectAssertions e a
 -> (CollectAssertions e a -> CollectAssertions e b)
 -> CollectAssertions e b)
-> LetExp (CollectAssertions e)
forall a b.
DinoType a =>
Text
-> CollectAssertions e a
-> (CollectAssertions e a -> CollectAssertions e b)
-> CollectAssertions e b
forall (e :: * -> *) a b.
(VarExp e, LetIntensional e, DinoType a) =>
Text
-> CollectAssertions e a
-> (CollectAssertions e a -> CollectAssertions e b)
-> CollectAssertions e b
forall (e :: * -> *).
(forall a b. DinoType a => Text -> e a -> (e a -> e b) -> e b)
-> LetExp e
letE :: Text
-> CollectAssertions e a
-> (CollectAssertions e a -> CollectAssertions e b)
-> CollectAssertions e b
$cletE :: forall (e :: * -> *) a b.
(VarExp e, LetIntensional e, DinoType a) =>
Text
-> CollectAssertions e a
-> (CollectAssertions e a -> CollectAssertions e b)
-> CollectAssertions e b
LetExp
             , proxy f -> CollectAssertions e r -> CollectAssertions e a
(forall (f :: Symbol) r a (proxy :: Symbol -> *).
 (KnownSymbol f, HasField f r a, DinoType a) =>
 proxy f -> CollectAssertions e r -> CollectAssertions e a)
-> FieldExp (CollectAssertions e)
forall (f :: Symbol) r a (proxy :: Symbol -> *).
(KnownSymbol f, HasField f r a, DinoType a) =>
proxy f -> CollectAssertions e r -> CollectAssertions e a
forall (e :: * -> *) (f :: Symbol) r a (proxy :: Symbol -> *).
(FieldExp e, KnownSymbol f, HasField f r a, DinoType a) =>
proxy f -> CollectAssertions e r -> CollectAssertions e a
forall (e :: * -> *).
(forall (f :: Symbol) r a (proxy :: Symbol -> *).
 (KnownSymbol f, HasField f r a, DinoType a) =>
 proxy f -> e r -> e a)
-> FieldExp e
getField :: proxy f -> CollectAssertions e r -> CollectAssertions e a
$cgetField :: forall (e :: * -> *) (f :: Symbol) r a (proxy :: Symbol -> *).
(FieldExp e, KnownSymbol f, HasField f r a, DinoType a) =>
proxy f -> CollectAssertions e r -> CollectAssertions e a
FieldExp
             , AnnExp ann
             , Text -> CollectAssertions e a
(forall a. DinoType a => Text -> CollectAssertions e a)
-> VarExp (CollectAssertions e)
forall a. DinoType a => Text -> CollectAssertions e a
forall (e :: * -> *) a.
(VarExp e, DinoType a) =>
Text -> CollectAssertions e a
forall (e :: * -> *).
(forall a. DinoType a => Text -> e a) -> VarExp e
varE :: Text -> CollectAssertions e a
$cvarE :: forall (e :: * -> *) a.
(VarExp e, DinoType a) =>
Text -> CollectAssertions e a
VarExp
             )
  -- TODO Use `Seq` instead of list.

instance AssertExp (CollectAssertions e) where
  assert :: Text
-> CollectAssertions e Bool
-> CollectAssertions e a
-> CollectAssertions e a
assert Text
lab =
    (Intensional (e :×: Fold [(Text, Assertion e)]) Bool
 -> Intensional (e :×: Fold [(Text, Assertion e)]) a
 -> Intensional (e :×: Fold [(Text, Assertion e)]) a)
-> CollectAssertions e Bool
-> CollectAssertions e a
-> CollectAssertions e a
coerce ((Intensional (e :×: Fold [(Text, Assertion e)]) Bool
  -> Intensional (e :×: Fold [(Text, Assertion e)]) a
  -> Intensional (e :×: Fold [(Text, Assertion e)]) a)
 -> CollectAssertions e Bool
 -> CollectAssertions e a
 -> CollectAssertions e a)
-> (Intensional (e :×: Fold [(Text, Assertion e)]) Bool
    -> Intensional (e :×: Fold [(Text, Assertion e)]) a
    -> Intensional (e :×: Fold [(Text, Assertion e)]) a)
-> CollectAssertions e Bool
-> CollectAssertions e a
-> CollectAssertions e a
forall a b. (a -> b) -> a -> b
$
    forall a b c.
((:×:) e (Fold [(Text, Assertion e)]) a
 -> (:×:) e (Fold [(Text, Assertion e)]) b
 -> (:×:) e (Fold [(Text, Assertion e)]) c)
-> Intensional (e :×: Fold [(Text, Assertion e)]) a
-> Intensional (e :×: Fold [(Text, Assertion e)]) b
-> Intensional (e :×: Fold [(Text, Assertion e)]) c
forall (e :: * -> *) a b c.
(e a -> e b -> e c)
-> Intensional e a -> Intensional e b -> Intensional e c
liftIntensional2 @(e :×: Fold [(Text, Assertion e)]) (((:×:) e (Fold [(Text, Assertion e)]) Bool
  -> (:×:) e (Fold [(Text, Assertion e)]) a
  -> (:×:) e (Fold [(Text, Assertion e)]) a)
 -> Intensional (e :×: Fold [(Text, Assertion e)]) Bool
 -> Intensional (e :×: Fold [(Text, Assertion e)]) a
 -> Intensional (e :×: Fold [(Text, Assertion e)]) a)
-> ((:×:) e (Fold [(Text, Assertion e)]) Bool
    -> (:×:) e (Fold [(Text, Assertion e)]) a
    -> (:×:) e (Fold [(Text, Assertion e)]) a)
-> Intensional (e :×: Fold [(Text, Assertion e)]) Bool
-> Intensional (e :×: Fold [(Text, Assertion e)]) a
-> Intensional (e :×: Fold [(Text, Assertion e)]) a
forall a b. (a -> b) -> a -> b
$
      \(e Bool
c :×: Fold [(Text, Assertion e)] Bool
_) (e a
a :×: Fold [(Text, Assertion e)] a
as) -> (e a
a e a
-> Fold [(Text, Assertion e)] a
-> (:×:) e (Fold [(Text, Assertion e)]) a
forall (e1 :: * -> *) (e2 :: * -> *) a.
e1 a -> e2 a -> (:×:) e1 e2 a
:×: (Fold [(Text, Assertion e)] a
as Fold [(Text, Assertion e)] a
-> Fold [(Text, Assertion e)] a -> Fold [(Text, Assertion e)] a
forall a. Semigroup a => a -> a -> a
<> [(Text, Assertion e)] -> Fold [(Text, Assertion e)] a
forall e a. e -> Fold e a
Fold [(Text
lab, e Bool -> Assertion e
forall (e :: * -> *). e Bool -> Assertion e
Assert e Bool
c)]))

  assertEq :: Text
-> CollectAssertions e a
-> CollectAssertions e a
-> CollectAssertions e a
assertEq Text
lab =
    (Intensional (e :×: Fold [(Text, Assertion e)]) a
 -> Intensional (e :×: Fold [(Text, Assertion e)]) a
 -> Intensional (e :×: Fold [(Text, Assertion e)]) a)
-> CollectAssertions e a
-> CollectAssertions e a
-> CollectAssertions e a
coerce ((Intensional (e :×: Fold [(Text, Assertion e)]) a
  -> Intensional (e :×: Fold [(Text, Assertion e)]) a
  -> Intensional (e :×: Fold [(Text, Assertion e)]) a)
 -> CollectAssertions e a
 -> CollectAssertions e a
 -> CollectAssertions e a)
-> (Intensional (e :×: Fold [(Text, Assertion e)]) a
    -> Intensional (e :×: Fold [(Text, Assertion e)]) a
    -> Intensional (e :×: Fold [(Text, Assertion e)]) a)
-> CollectAssertions e a
-> CollectAssertions e a
-> CollectAssertions e a
forall a b. (a -> b) -> a -> b
$
    forall a b c.
((:×:) e (Fold [(Text, Assertion e)]) a
 -> (:×:) e (Fold [(Text, Assertion e)]) b
 -> (:×:) e (Fold [(Text, Assertion e)]) c)
-> Intensional (e :×: Fold [(Text, Assertion e)]) a
-> Intensional (e :×: Fold [(Text, Assertion e)]) b
-> Intensional (e :×: Fold [(Text, Assertion e)]) c
forall (e :: * -> *) a b c.
(e a -> e b -> e c)
-> Intensional e a -> Intensional e b -> Intensional e c
liftIntensional2 @(e :×: Fold [(Text, Assertion e)]) (((:×:) e (Fold [(Text, Assertion e)]) a
  -> (:×:) e (Fold [(Text, Assertion e)]) a
  -> (:×:) e (Fold [(Text, Assertion e)]) a)
 -> Intensional (e :×: Fold [(Text, Assertion e)]) a
 -> Intensional (e :×: Fold [(Text, Assertion e)]) a
 -> Intensional (e :×: Fold [(Text, Assertion e)]) a)
-> ((:×:) e (Fold [(Text, Assertion e)]) a
    -> (:×:) e (Fold [(Text, Assertion e)]) a
    -> (:×:) e (Fold [(Text, Assertion e)]) a)
-> Intensional (e :×: Fold [(Text, Assertion e)]) a
-> Intensional (e :×: Fold [(Text, Assertion e)]) a
-> Intensional (e :×: Fold [(Text, Assertion e)]) a
forall a b. (a -> b) -> a -> b
$
      \(e a
ref :×: Fold [(Text, Assertion e)] a
_) (e a
act :×: Fold [(Text, Assertion e)] a
as) ->
        (e a
act e a
-> Fold [(Text, Assertion e)] a
-> (:×:) e (Fold [(Text, Assertion e)]) a
forall (e1 :: * -> *) (e2 :: * -> *) a.
e1 a -> e2 a -> (:×:) e1 e2 a
:×: (Fold [(Text, Assertion e)] a
as Fold [(Text, Assertion e)] a
-> Fold [(Text, Assertion e)] a -> Fold [(Text, Assertion e)] a
forall a. Semigroup a => a -> a -> a
<> [(Text, Assertion e)] -> Fold [(Text, Assertion e)] a
forall e a. e -> Fold e a
Fold [(Text
lab, e a -> e a -> Assertion e
forall a (e :: * -> *). (Eq a, Show a) => e a -> e a -> Assertion e
AssertEq e a
ref e a
act)]))

-- Here is an example of how to "run" `CollectAssertions`:
--
--     collectAssertions ::
--          (ConstExp e, NumExp e, CompareExp e, VarExp e, LetIntensional e)
--       => (forall e'. ( ConstExp e'
--                      , NumExp e'
--                      , CompareExp e'
--                      , AssertExp e'
--                      , LetExp e'
--                      ) =>
--                        Exp e' a
--          )
--       -> [(Text, Assertion e)]
--     collectAssertions =
--       fold . prodSnd . prodSnd . unIntensional . unCollectAssertions . unExp
--
-- Note that the interpretation type is different in the argument and the
-- result. But the two are related in the following way:
--
--   * FOS classes that appear as constraints on `e'` must also appear as
--     constraints on `e`.
--   * Each HOS class constraint on `e'` requires a corresponding intensional
--     class constraint on `e`.
--
-- Note that the `AssertExp` constraint on `e'` isn't needed on `e`.