aws-arn-0.3.0.0: src/Network/AWS/ARN/Internal/Lens.hs
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
-- |
--
-- Module : Network.AWS.ARN.Internal.Lens
-- Copyright : (C) 2020-2022 Bellroy Pty Ltd
-- License : BSD-3-Clause
-- Maintainer : Bellroy Tech Team <haskell@bellroy.com>
-- Stability : experimental
--
-- Reimplement a few lens types and combinators to keep the dependency
-- footprint down.
module Network.AWS.ARN.Internal.Lens where
import Data.Functor.Const (Const (..))
import Data.Functor.Identity (Identity (..))
import Data.Monoid (First (..))
import Data.Profunctor (Profunctor (..))
import Data.Profunctor.Choice (Choice (..))
import Data.Tagged (Tagged (..))
type Lens' s a = forall f. Functor f => (a -> f a) -> s -> f s
type Getting r s a = (a -> Const r a) -> s -> Const r s
type Setter s a = (a -> Identity a) -> s -> Identity s
set :: Setter s a -> a -> s -> s
set l = over l . const
{-# INLINE set #-}
(.~) :: Setter s a -> a -> s -> s
(.~) = set
infixr 4 .~
over :: Setter s a -> (a -> a) -> s -> s
over l f = runIdentity . l (Identity . f)
{-# INLINE over #-}
(^.) :: s -> Getting a s a -> a
s ^. l = getConst $ l Const s
infixl 8 ^.
type Prism' s a =
forall p f. (Choice p, Applicative f) => p a (f a) -> p s (f s)
prism' :: forall s a. (a -> s) -> (s -> Maybe a) -> Prism' s a
prism' inj prj p = dimap prj' inj' $ right' p
where
inj' :: Applicative f => Either s (f a) -> f s
inj' = either pure (fmap inj)
prj' :: s -> Either s a
prj' s = maybe (Left s) Right $ prj s
{-# INLINE prism' #-}
preview :: Prism' s a -> s -> Maybe a
preview p s = (getFirst . getConst . ($ s)) $ p (Const . First . Just)
{-# INLINE preview #-}
review :: Prism' s a -> a -> s
review p = runIdentity . unTagged . p . Tagged . Identity
{-# INLINE review #-}
(^?) :: s -> Prism' s a -> Maybe a
s ^? p = preview p s
{-# INLINE (^?) #-}
infixl 8 ^?
type Traversal' s a = forall f. Applicative f => (a -> f a) -> s -> f s
ix :: Int -> Traversal' [a] a
ix 0 f (x : xs) = (: xs) <$> f x
ix n f (x : xs) = (x :) <$> ix (n - 1) f xs
ix _ _ [] = pure []
type Iso' s a = forall p f. (Profunctor p, Functor f) => p a (f a) -> p s (f s)
type AnIso' s a = Exchange a a a (Identity a) -> Exchange a a s (Identity s)
data Exchange a b s t = Exchange (s -> a) (b -> t)
instance Profunctor (Exchange a b) where
dimap f g (Exchange sa bt) = Exchange (sa . f) (g . bt)
iso :: (s -> a) -> (a -> s) -> Iso' s a
iso f t = dimap f (fmap t)
{-# INLINE iso #-}
from :: AnIso' s a -> Iso' a s
from l = iso (runIdentity . t) f
where
Exchange f t = l $ Exchange id Identity