{-# LANGUAGE CPP #-} {-# LANGUAGE RankNTypes #-} -- | A small module defining the least you need to support -- van-Laarhoven lenses without depending on @lens@ or @microlens@ or ... -- -- See @lens@ package for the documentation. -- -- I copy this around. -- -- Assumes GHC-7.8 / base-4.7; with "Data.Coerce". -- -- module Control.Lens.Yocto ( -- * Types Optic, Optic', LensLike, LensLike', Lens, Lens', Traversal, Traversal', #ifdef MIN_VERSION_profunctors Prism, Prism', Iso, Iso', #endif -- * Operations view, set, over, -- * Operators (<&>), -- * Constructors #ifdef MIN_VERSION_profunctors iso, prism, prism', #endif )where import Control.Applicative (Applicative (..), Const (..)) import Data.Coerce (coerce) import Data.Functor.Identity (Identity (..)) import Prelude (Functor (..), const, (.)) #ifdef MIN_VERSION_profunctors import Data.Profunctor (Choice (..), Profunctor (..)) import Prelude (Either (..), Maybe, either, maybe, (.)) #endif #if MIN_VERSION_base(4,11,0) import Data.Functor ((<&>)) #endif ------------------------------------------------------------------------------- -- Types ------------------------------------------------------------------------------- type Optic p f s t a b = p a (f b) -> p s (f t) type Optic' p f s a = Optic p f s s a a type LensLike f s t a b = Optic (->) f s t a b type LensLike' f s a = LensLike f s s a a type Lens s t a b = forall f. Functor f => LensLike f s t a b type Lens' s a = Lens s s a a type Traversal s t a b = forall f. Applicative f => LensLike f s t a b type Traversal' s a = Lens s s a a #ifdef MIN_VERSION_profunctors type Prism s t a b = forall p f. (Choice p, Applicative f) => Optic p f s t a b type Prism' s a = Prism s s a a type Iso s t a b = forall p f. (Profunctor p, Functor f) => Optic p f s t a b type Iso' s a = Iso s s a a #endif ------------------------------------------------------------------------------- -- Operations ------------------------------------------------------------------------------- view :: LensLike' (Const a) s a -> s -> a view l = coerce (l Const) {-# INLINE view #-} set :: LensLike Identity s t a b -> b -> s -> t set l = over l . const {-# INLINE set #-} over :: LensLike Identity s t a b -> (a -> b) -> s -> t over = coerce {-# INLINE over #-} ------------------------------------------------------------------------------- -- Operators ------------------------------------------------------------------------------- #if !MIN_VERSION_base(4,11,0) (<&>) :: Functor f => f a -> (a -> b) -> f b as <&> f = fmap f as infixl 1 <&> #endif ------------------------------------------------------------------------------- -- Constructors ------------------------------------------------------------------------------- #ifdef MIN_VERSION_profunctors iso :: (s -> a) -> (b -> t) -> Iso s t a b iso sa bt = dimap sa (fmap bt) {-# INLINE iso #-} prism :: (b -> t) -> (s -> Either t a) -> Prism s t a b prism bt seta = dimap seta (either pure (fmap bt)) . right' {-# INLINE prism #-} prism' :: (b -> s) -> (s -> Maybe a) -> Prism s s a b prism' bs sma = prism bs (\s -> maybe (Left s) Right (sma s)) {-# INLINE prism' #-} #endif