{-# OPTIONS_HADDOCK not-home #-}
module Optics.Internal.Utils
( Identity'(..)
, wrapIdentity'
, unwrapIdentity'
, Traversed(..)
, runTraversed
, OrT(..)
, wrapOrT
, (#.)
, (.#)
) where
import qualified Data.Semigroup as SG
import Data.Profunctor.Indexed
data Identity' a = Identity' {-# UNPACK #-} !() a
deriving Functor
instance Applicative Identity' where
pure a = Identity' () a
{-# INLINE pure #-}
Identity' () f <*> Identity' () x = Identity' () (f x)
{-# INLINE (<*>) #-}
instance Mapping (Star Identity') where
roam f (Star k) = Star $ wrapIdentity' . f (unwrapIdentity' . k)
iroam f (Star k) = Star $ wrapIdentity' . f (\_ -> unwrapIdentity' . k)
{-# INLINE roam #-}
{-# INLINE iroam #-}
instance Mapping (IxStar Identity') where
roam f (IxStar k) =
IxStar $ \i -> wrapIdentity' . f (unwrapIdentity' . k i)
iroam f (IxStar k) =
IxStar $ \ij -> wrapIdentity' . f (\i -> unwrapIdentity' . k (ij i))
{-# INLINE roam #-}
{-# INLINE iroam #-}
wrapIdentity' :: a -> Identity' a
wrapIdentity' a = Identity' (a `seq` ()) a
{-# INLINE wrapIdentity' #-}
unwrapIdentity' :: Identity' a -> a
unwrapIdentity' (Identity' () a) = a
{-# INLINE unwrapIdentity' #-}
newtype Traversed f a = Traversed (f a)
runTraversed :: Functor f => Traversed f a -> f ()
runTraversed (Traversed fa) = () <$ fa
{-# INLINE runTraversed #-}
instance Applicative f => SG.Semigroup (Traversed f a) where
Traversed ma <> Traversed mb = Traversed (ma *> mb)
{-# INLINE (<>) #-}
instance Applicative f => Monoid (Traversed f a) where
mempty = Traversed (pure (error "Traversed: value used"))
mappend = (SG.<>)
{-# INLINE mempty #-}
{-# INLINE mappend #-}
data OrT f a = OrT !Bool (f a)
deriving Functor
instance Applicative f => Applicative (OrT f) where
pure = OrT False . pure
OrT a f <*> OrT b x = OrT (a || b) (f <*> x)
{-# INLINE pure #-}
{-# INLINE (<*>) #-}
wrapOrT :: f a -> OrT f a
wrapOrT = OrT True
{-# INLINE wrapOrT #-}