{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE CPP #-}
#if __GLASGOW_HASKELL__ >= 704
{-# LANGUAGE Safe #-}
#elif __GLASGOW_HASKELL__ >= 702
{-# LANGUAGE Trustworthy #-}
#endif
-----------------------------------------------------------------------------
-- |
-- Module      :  Control.Comonad.Env.Class
-- Copyright   :  (C) 2008-2015 Edward Kmett
-- License     :  BSD-style (see the file LICENSE)
--
-- Maintainer  :  Edward Kmett <ekmett@gmail.com>
-- Stability   :  experimental
-- Portability :  non-portable (fundeps, MPTCs)
----------------------------------------------------------------------------
module Control.Comonad.Env.Class
  ( ComonadEnv(..)
  , asks
  ) where

import Control.Comonad
import Control.Comonad.Trans.Class
import qualified Control.Comonad.Trans.Env as Env
import Control.Comonad.Trans.Store
import Control.Comonad.Trans.Traced
import Control.Comonad.Trans.Identity
import Data.Semigroup

class Comonad w => ComonadEnv e w | w -> e where
  ask :: w a -> e

asks :: ComonadEnv e w => (e -> e') -> w a -> e'
asks :: forall e (w :: * -> *) e' a.
ComonadEnv e w =>
(e -> e') -> w a -> e'
asks e -> e'
f w a
wa = e -> e'
f (forall e (w :: * -> *) a. ComonadEnv e w => w a -> e
ask w a
wa)
{-# INLINE asks #-}

instance Comonad w => ComonadEnv e (Env.EnvT e w) where
  ask :: forall a. EnvT e w a -> e
ask = forall e (w :: * -> *) a. EnvT e w a -> e
Env.ask

instance ComonadEnv e ((,)e) where
  ask :: forall a. (e, a) -> e
ask = forall e a. (e, a) -> e
fst

instance ComonadEnv e (Arg e) where
  ask :: forall a. Arg e a -> e
ask (Arg e
e a
_) = e
e

lowerAsk :: (ComonadEnv e w, ComonadTrans t) => t w a -> e
lowerAsk :: forall e (w :: * -> *) (t :: (* -> *) -> * -> *) a.
(ComonadEnv e w, ComonadTrans t) =>
t w a -> e
lowerAsk = forall e (w :: * -> *) a. ComonadEnv e w => w a -> e
ask forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: (* -> *) -> * -> *) (w :: * -> *) a.
(ComonadTrans t, Comonad w) =>
t w a -> w a
lower
{-# INLINE lowerAsk #-}

instance ComonadEnv e w => ComonadEnv e (StoreT t w) where
  ask :: forall a. StoreT t w a -> e
ask = forall e (w :: * -> *) (t :: (* -> *) -> * -> *) a.
(ComonadEnv e w, ComonadTrans t) =>
t w a -> e
lowerAsk

instance ComonadEnv e w => ComonadEnv e (IdentityT w) where
  ask :: forall a. IdentityT w a -> e
ask = forall e (w :: * -> *) (t :: (* -> *) -> * -> *) a.
(ComonadEnv e w, ComonadTrans t) =>
t w a -> e
lowerAsk

instance (ComonadEnv e w, Monoid m) => ComonadEnv e (TracedT m w) where
  ask :: forall a. TracedT m w a -> e
ask = forall e (w :: * -> *) (t :: (* -> *) -> * -> *) a.
(ComonadEnv e w, ComonadTrans t) =>
t w a -> e
lowerAsk