module Symantic.Semantics.Reader where

import Data.Function (const, (.))

import Symantic.Syntaxes.Classes hiding (const, (.))
import Symantic.Syntaxes.Derive

-- * Type 'Reader'

-- | An intermediate interpreter exposing an environment.
newtype Reader r sem a = Reader {forall r (sem :: * -> *) a. Reader r sem a -> r -> sem a
unReader :: r -> sem a}

type instance Derived (Reader r sem) = sem
instance LiftDerived (Reader r sem) where
  liftDerived :: forall a. Derived (Reader r sem) a -> Reader r sem a
liftDerived = (r -> sem a) -> Reader r sem a
forall r (sem :: * -> *) a. (r -> sem a) -> Reader r sem a
Reader ((r -> sem a) -> Reader r sem a)
-> (sem a -> r -> sem a) -> sem a -> Reader r sem a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. sem a -> r -> sem a
forall a b. a -> b -> a
const
instance LiftDerived1 (Reader r sem) where
  liftDerived1 :: forall a b.
(Derived (Reader r sem) a -> Derived (Reader r sem) b)
-> Reader r sem a -> Reader r sem b
liftDerived1 Derived (Reader r sem) a -> Derived (Reader r sem) b
f Reader r sem a
a = (r -> sem b) -> Reader r sem b
forall r (sem :: * -> *) a. (r -> sem a) -> Reader r sem a
Reader (sem a -> sem b
Derived (Reader r sem) a -> Derived (Reader r sem) b
f (sem a -> sem b) -> (r -> sem a) -> r -> sem b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Reader r sem a -> r -> sem a
forall r (sem :: * -> *) a. Reader r sem a -> r -> sem a
unReader Reader r sem a
a)
instance LiftDerived2 (Reader r sem) where
  liftDerived2 :: forall a b c.
(Derived (Reader r sem) a
 -> Derived (Reader r sem) b -> Derived (Reader r sem) c)
-> Reader r sem a -> Reader r sem b -> Reader r sem c
liftDerived2 Derived (Reader r sem) a
-> Derived (Reader r sem) b -> Derived (Reader r sem) c
f Reader r sem a
a Reader r sem b
b = (r -> sem c) -> Reader r sem c
forall r (sem :: * -> *) a. (r -> sem a) -> Reader r sem a
Reader (\r
r -> Derived (Reader r sem) a
-> Derived (Reader r sem) b -> Derived (Reader r sem) c
f (Reader r sem a -> r -> sem a
forall r (sem :: * -> *) a. Reader r sem a -> r -> sem a
unReader Reader r sem a
a r
r) (Reader r sem b -> r -> sem b
forall r (sem :: * -> *) a. Reader r sem a -> r -> sem a
unReader Reader r sem b
b r
r))
instance LiftDerived3 (Reader r sem) where
  liftDerived3 :: forall a b c d.
(Derived (Reader r sem) a
 -> Derived (Reader r sem) b
 -> Derived (Reader r sem) c
 -> Derived (Reader r sem) d)
-> Reader r sem a
-> Reader r sem b
-> Reader r sem c
-> Reader r sem d
liftDerived3 Derived (Reader r sem) a
-> Derived (Reader r sem) b
-> Derived (Reader r sem) c
-> Derived (Reader r sem) d
f Reader r sem a
a Reader r sem b
b Reader r sem c
c = (r -> sem d) -> Reader r sem d
forall r (sem :: * -> *) a. (r -> sem a) -> Reader r sem a
Reader (\r
r -> Derived (Reader r sem) a
-> Derived (Reader r sem) b
-> Derived (Reader r sem) c
-> Derived (Reader r sem) d
f (Reader r sem a -> r -> sem a
forall r (sem :: * -> *) a. Reader r sem a -> r -> sem a
unReader Reader r sem a
a r
r) (Reader r sem b -> r -> sem b
forall r (sem :: * -> *) a. Reader r sem a -> r -> sem a
unReader Reader r sem b
b r
r) (Reader r sem c -> r -> sem c
forall r (sem :: * -> *) a. Reader r sem a -> r -> sem a
unReader Reader r sem c
c r
r))
instance LiftDerived4 (Reader r sem) where
  liftDerived4 :: forall a b c d e.
(Derived (Reader r sem) a
 -> Derived (Reader r sem) b
 -> Derived (Reader r sem) c
 -> Derived (Reader r sem) d
 -> Derived (Reader r sem) e)
-> Reader r sem a
-> Reader r sem b
-> Reader r sem c
-> Reader r sem d
-> Reader r sem e
liftDerived4 Derived (Reader r sem) a
-> Derived (Reader r sem) b
-> Derived (Reader r sem) c
-> Derived (Reader r sem) d
-> Derived (Reader r sem) e
f Reader r sem a
a Reader r sem b
b Reader r sem c
c Reader r sem d
d = (r -> sem e) -> Reader r sem e
forall r (sem :: * -> *) a. (r -> sem a) -> Reader r sem a
Reader (\r
r -> Derived (Reader r sem) a
-> Derived (Reader r sem) b
-> Derived (Reader r sem) c
-> Derived (Reader r sem) d
-> Derived (Reader r sem) e
f (Reader r sem a -> r -> sem a
forall r (sem :: * -> *) a. Reader r sem a -> r -> sem a
unReader Reader r sem a
a r
r) (Reader r sem b -> r -> sem b
forall r (sem :: * -> *) a. Reader r sem a -> r -> sem a
unReader Reader r sem b
b r
r) (Reader r sem c -> r -> sem c
forall r (sem :: * -> *) a. Reader r sem a -> r -> sem a
unReader Reader r sem c
c r
r) (Reader r sem d -> r -> sem d
forall r (sem :: * -> *) a. Reader r sem a -> r -> sem a
unReader Reader r sem d
d r
r))

instance Unabstractable sem => Unabstractable (Reader r sem)
instance Abstractable sem => Abstractable (Reader r sem) where
  lam :: forall a b.
(Reader r sem a -> Reader r sem b) -> Reader r sem (a -> b)
lam Reader r sem a -> Reader r sem b
f = (r -> sem (a -> b)) -> Reader r sem (a -> b)
forall r (sem :: * -> *) a. (r -> sem a) -> Reader r sem a
Reader (\r
r -> (sem a -> sem b) -> sem (a -> b)
forall (sem :: * -> *) a b.
Abstractable sem =>
(sem a -> sem b) -> sem (a -> b)
lam ((Reader r sem b -> r -> sem b
forall r (sem :: * -> *) a. Reader r sem a -> r -> sem a
`unReader` r
r) (Reader r sem b -> sem b)
-> (sem a -> Reader r sem b) -> sem a -> sem b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Reader r sem a -> Reader r sem b
f (Reader r sem a -> Reader r sem b)
-> (sem a -> Reader r sem a) -> sem a -> Reader r sem b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. sem a -> Reader r sem a
forall (sem :: * -> *) a. LiftDerived sem => Derived sem a -> sem a
liftDerived))
  lam1 :: forall a b.
(Reader r sem a -> Reader r sem b) -> Reader r sem (a -> b)
lam1 Reader r sem a -> Reader r sem b
f = (r -> sem (a -> b)) -> Reader r sem (a -> b)
forall r (sem :: * -> *) a. (r -> sem a) -> Reader r sem a
Reader (\r
r -> (sem a -> sem b) -> sem (a -> b)
forall (sem :: * -> *) a b.
Abstractable sem =>
(sem a -> sem b) -> sem (a -> b)
lam1 ((Reader r sem b -> r -> sem b
forall r (sem :: * -> *) a. Reader r sem a -> r -> sem a
`unReader` r
r) (Reader r sem b -> sem b)
-> (sem a -> Reader r sem b) -> sem a -> sem b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Reader r sem a -> Reader r sem b
f (Reader r sem a -> Reader r sem b)
-> (sem a -> Reader r sem a) -> sem a -> Reader r sem b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. sem a -> Reader r sem a
forall (sem :: * -> *) a. LiftDerived sem => Derived sem a -> sem a
liftDerived))
instance Functionable sem => Functionable (Reader r sem)
instance Anythingable sem => Anythingable (Reader r sem)
instance Constantable c sem => Constantable c (Reader r sem)
instance Eitherable sem => Eitherable (Reader r sem)
instance Equalable sem => Equalable (Reader r sem)
instance IfThenElseable sem => IfThenElseable (Reader r sem)

-- Using 'Inferable' with a specific @a@ and keeping @sem@ polymorphic
-- is more usual; hence commenting this instance that would overlap.
--instance Inferable a sem => Inferable a (Reader r sem)
instance Listable sem => Listable (Reader r sem)
instance Maybeable sem => Maybeable (Reader r sem)
instance IsoFunctor sem => IsoFunctor (Reader r sem)
instance (ProductFunctor sem, IsoFunctor sem) => ProductFunctor (Reader r sem)
instance (SumFunctor sem, IsoFunctor sem) => SumFunctor (Reader r sem)
instance AlternativeFunctor sem => AlternativeFunctor (Reader r sem)
instance Dicurryable sem => Dicurryable (Reader r sem)
instance Emptyable sem => Emptyable (Reader r sem)
instance Semigroupable sem => Semigroupable (Reader r sem)
instance Optionable sem => Optionable (Reader r sem)
instance Repeatable sem => Repeatable (Reader r sem)

-- instance Permutable sem => Permutable (Reader r sem)
instance Voidable sem => Voidable (Reader r sem)
instance Substractable sem => Substractable (Reader r sem)