{-# LANGUAGE CPP #-} -- | parts of lens that would be imported if we depended on it module LensDefs (module LensDefs, module Control.Applicative, Choice, Profunctor, Coercible) where import Data.Profunctor import Data.Profunctor.Unsafe import Control.Applicative import Control.Monad.Identity import Unsafe.Coerce #if __GLASGOW_HASKELL__ > 707 import GHC.Exts(Coercible) #else import GHC.Exts(Constraint) -- | for ghc-7.6 we don't have coercible type Coercible a b = (() :: Constraint) #endif type Equality' s a = forall p (f :: * -> *). a `p` f a -> s `p` f s {- | if we write @f' = simple . f@, then the inferred type is > f' :: (s ~ t, _) => Lens s t a b which normally will let ghc figure out (a~b). However with the types that come up in HList this can only be figure out with concrete types, so we use isSimple instead which also specifies (a~b). -} isSimple :: optic ~ (p a (f a) -> p s (f s)) => optic -> optic isSimple = id -- alternatively: isSimple x = simple . x . simple simple :: Equality' a a simple = id -- Used by doctests (which should probably just import Control.Lens...) infixl 1 & x & f = f x infixr 4 %~ l %~ f = \t -> runIdentity $ l (rmap Identity f) t iso :: (Profunctor p, Functor f) => (s -> a) -> (b -> t) -> p a (f b) -> p s (f t) iso sa bt = dimap sa (fmap bt) -- | iso, except assumes that the functions supplied could -- be 'Data.Coerce.coerce' isoNewtype :: (Profunctor p, Functor f, Coercible b t, -- Coercible (f b) (f t) -- is really needed but that complicates types later on (since f is forall'd) Coercible a s) => (s -> a) -> (b -> t) -> p a (f b) -> p s (f t) isoNewtype sa _bt x = coerceBT x .# sa where coerceBT :: p a (f b) -> p a (f t) coerceBT = unsafeCoerce prism :: (b -> t) -> (s -> Either t a) -> (forall p f. (Choice p, Applicative f) => p a (f b) -> p s (f t)) prism bt seta = dimap seta (either pure (fmap bt)) . right' prism' :: (a -> s) -> (s -> Maybe a) -> (forall p f. (Choice p, Applicative f) => p a (f a) -> p s (f s)) prism' bs sma = prism bs (\s -> maybe (Left s) Right (sma s))