module Symantic.Reader where import Data.Function ((.), const) import Symantic.Classes hiding (const, (.)) import Symantic.Derive -- * Type 'Reader' -- | An intermediate interpreter exposing an environment. newtype Reader r sem a = Reader { unReader :: r -> sem a } type instance Derived (Reader r sem) = sem instance LiftDerived (Reader r sem) where liftDerived = Reader . const instance LiftDerived1 (Reader r sem) where liftDerived1 f a = Reader (f . unReader a) instance LiftDerived2 (Reader r sem) where liftDerived2 f a b = Reader (\r -> f (unReader a r) (unReader b r)) instance LiftDerived3 (Reader r sem) where liftDerived3 f a b c = Reader (\r -> f (unReader a r) (unReader b r) (unReader c r)) instance LiftDerived4 (Reader r sem) where liftDerived4 f a b c d = Reader (\r -> f (unReader a r) (unReader b r) (unReader c r) (unReader d r)) instance Abstractable sem => Abstractable (Reader r sem) where lam f = Reader (\r -> lam ((`unReader` r) . f . liftDerived)) lam1 f = Reader (\r -> lam1 ((`unReader` r) . f . 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 Routable sem => Routable (Reader r sem) instance Voidable sem => Voidable (Reader r sem) instance Substractable sem => Substractable (Reader r sem)