{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE CPP #-}
#if __GLASGOW_HASKELL__ >= 702 && __GLASGOW_HASKELL__ <= 708
{-# LANGUAGE Trustworthy #-}
#endif
module Data.Profunctor.Sieve
  ( Sieve(..)
  , Cosieve(..)
  ) where
import Control.Applicative
import Control.Arrow
import Control.Comonad
import Data.Functor.Identity
import Data.Profunctor
import Data.Proxy
import Data.Tagged
class (Profunctor p, Functor f) => Sieve p f | p -> f where
  sieve :: p a b -> a -> f b
instance Sieve (->) Identity where
  sieve f = Identity . f
  {-# INLINE sieve #-}
instance (Monad m, Functor m) => Sieve (Kleisli m) m where
  sieve = runKleisli
  {-# INLINE sieve #-}
instance Functor f => Sieve (Star f) f where
  sieve = runStar
  {-# INLINE sieve #-}
instance Sieve (Forget r) (Const r) where
  sieve = (Const .) . runForget
  {-# INLINE sieve #-}
class (Profunctor p, Functor f) => Cosieve p f | p -> f where
  cosieve :: p a b -> f a -> b
instance Cosieve (->) Identity where
  cosieve f (Identity d) = f d
  {-# INLINE cosieve #-}
instance Functor w => Cosieve (Cokleisli w) w where
  cosieve = runCokleisli
  {-# INLINE cosieve #-}
instance Cosieve Tagged Proxy where
  cosieve (Tagged a) _ = a
  {-# INLINE cosieve #-}
instance Functor f => Cosieve (Costar f) f where
  cosieve = runCostar
  {-# INLINE cosieve #-}