--- /dev/null
+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 repr a = Reader { unReader :: r -> repr a }
+
+type instance Derived (Reader r repr) = repr
+instance LiftDerived (Reader r repr) where
+ liftDerived = Reader . const
+instance LiftDerived1 (Reader r repr) where
+ liftDerived1 f a = Reader (f . unReader a)
+instance LiftDerived2 (Reader r repr) where
+ liftDerived2 f a b = Reader (\r -> f (unReader a r) (unReader b r))
+instance LiftDerived3 (Reader r repr) where
+ liftDerived3 f a b c = Reader (\r -> f (unReader a r) (unReader b r) (unReader c r))
+instance LiftDerived4 (Reader r repr) where
+ liftDerived4 f a b c d = Reader (\r -> f (unReader a r) (unReader b r) (unReader c r) (unReader d r))
+
+instance Abstractable repr => Abstractable (Reader r repr) where
+ lam f = Reader (\r -> lam ((`unReader` r) . f . liftDerived))
+ lam1 f = Reader (\r -> lam1 ((`unReader` r) . f . liftDerived))
+instance Functionable repr => Functionable (Reader r repr)
+instance Anythingable repr => Anythingable (Reader r repr)
+instance Constantable c repr => Constantable c (Reader r repr)
+instance Eitherable repr => Eitherable (Reader r repr)
+instance Equalable repr => Equalable (Reader r repr)
+instance IfThenElseable repr => IfThenElseable (Reader r repr)
+-- Using 'Inferable' with a specific @a@ and keeping @repr@ polymorphic
+-- is more usual; hence commenting this instance that would overlap.
+--instance Inferable a repr => Inferable a (Reader r repr)
+instance Listable repr => Listable (Reader r repr)
+instance Maybeable repr => Maybeable (Reader r repr)
+instance IsoFunctor repr => IsoFunctor (Reader r repr)
+instance (ProductFunctor repr, IsoFunctor repr) => ProductFunctor (Reader r repr)
+instance (SumFunctor repr, IsoFunctor repr) => SumFunctor (Reader r repr)
+instance AlternativeFunctor repr => AlternativeFunctor (Reader r repr)
+instance Dicurryable repr => Dicurryable (Reader r repr)
+instance Emptyable repr => Emptyable (Reader r repr)
+instance Semigroupable repr => Semigroupable (Reader r repr)
+instance Optionable repr => Optionable (Reader r repr)
+instance Repeatable repr => Repeatable (Reader r repr)
+-- instance Permutable repr => Permutable (Reader r repr)
+instance Routable repr => Routable (Reader r repr)
+instance Voidable repr => Voidable (Reader r repr)
+instance Substractable repr => Substractable (Reader r repr)