module Pandora.Paradigm.Inventory.Environmental (Environmental (..), env, local) where import Pandora.Core.Morphism (identity, (.), (!)) import Pandora.Pattern.Functor.Covariant (Covariant ((<$>))) import Pandora.Pattern.Functor.Pointable (Pointable (point)) import Pandora.Pattern.Functor.Applicative (Applicative ((<*>))) import Pandora.Pattern.Functor.Bindable (Bindable ((>>=))) import Pandora.Pattern.Functor.Monad (Monad) import Pandora.Pattern.Functor.Divariant (($)) newtype Environmental e a = Environmental (e -> a) environmentally :: e -> Environmental e a -> a environmentally e (Environmental f) = f e instance Covariant (Environmental e) where f <$> Environmental x = Environmental $ f . x instance Pointable (Environmental e) where point x = Environmental (x !) instance Applicative (Environmental e) where f <*> x = Environmental $ \e -> environmentally e f $ environmentally e x instance Bindable (Environmental e) where Environmental x >>= f = Environmental $ \e -> environmentally e . f . x $ e instance Monad (Environmental e) where env :: Environmental e e env = Environmental identity local :: (e -> e) -> Environmental e a -> Environmental e a local f (Environmental x) = Environmental $ x . f