{-# LANGUAGE DataKinds #-}
{-# LANGUAGE TypeFamilyDependencies #-}
module Optics.Re
( ReversibleOptic(..)
) where
import Data.Coerce
import Data.Profunctor.Indexed
import Optics.Internal.Bi
import Optics.Internal.Indexed
import Optics.Internal.Optic
class ReversibleOptic k where
type ReversedOptic k = r | r -> k
re
:: "re" `AcceptsEmptyIndices` is
=> Optic k is s t a b
-> Optic (ReversedOptic k) is b a t s
instance ReversibleOptic An_Iso where
type ReversedOptic An_Iso = An_Iso
re o = Optic (re__ o)
{-# INLINE re #-}
instance ReversibleOptic A_Prism where
type ReversedOptic A_Prism = A_ReversedPrism
re o = Optic (re__ o)
{-# INLINE re #-}
instance ReversibleOptic A_ReversedPrism where
type ReversedOptic A_ReversedPrism = A_Prism
re o = Optic (re__ o)
{-# INLINE re #-}
instance ReversibleOptic A_Lens where
type ReversedOptic A_Lens = A_ReversedLens
re o = Optic (re__ o)
{-# INLINE re #-}
instance ReversibleOptic A_ReversedLens where
type ReversedOptic A_ReversedLens = A_Lens
re o = Optic (re__ o)
{-# INLINE re #-}
instance ReversibleOptic A_Getter where
type ReversedOptic A_Getter = A_Review
re o = Optic (re__ o)
{-# INLINE re #-}
instance ReversibleOptic A_Review where
type ReversedOptic A_Review = A_Getter
re o = Optic (re__ o)
{-# INLINE re #-}
re__
:: (Profunctor p, Constraints k (Re p a b))
=> Optic k NoIx s t a b
-> Optic__ p i i b a t s
re__ o = unRe (getOptic o (Re id))
{-# INLINE re__ #-}
newtype Re p s t i a b = Re { unRe :: p i b a -> p i t s }
instance Profunctor p => Profunctor (Re p s t) where
dimap f g (Re p) = Re (p . dimap g f)
lmap f (Re p) = Re (p . rmap f)
rmap g (Re p) = Re (p . lmap g)
{-# INLINE dimap #-}
{-# INLINE lmap #-}
{-# INLINE rmap #-}
lcoerce' = lmap coerce
rcoerce' = rmap coerce
{-# INLINE lcoerce' #-}
{-# INLINE rcoerce' #-}
conjoined__ = error "conjoined__(Re) shouldn't be reachable"
ixcontramap = error "ixcontramap(Re) shouldn't be reachable"
instance Bicontravariant p => Bifunctor (Re p s t) where
bimap f g (Re p) = Re (p . contrabimap g f)
first f (Re p) = Re (p . contrasecond f)
second g (Re p) = Re (p . contrafirst g)
{-# INLINE bimap #-}
{-# INLINE first #-}
{-# INLINE second #-}
instance Bifunctor p => Bicontravariant (Re p s t) where
contrabimap f g (Re p) = Re (p . bimap g f)
contrafirst f (Re p) = Re (p . second f)
contrasecond g (Re p) = Re (p . first g)
{-# INLINE contrabimap #-}
{-# INLINE contrafirst #-}
{-# INLINE contrasecond #-}
instance Strong p => Costrong (Re p s t) where
unfirst (Re p) = Re (p . first')
unsecond (Re p) = Re (p . second')
{-# INLINE unfirst #-}
{-# INLINE unsecond #-}
instance Costrong p => Strong (Re p s t) where
first' (Re p) = Re (p . unfirst)
second' (Re p) = Re (p . unsecond)
{-# INLINE first' #-}
{-# INLINE second' #-}
ilinear _ = error "ilinear(Re) shouldn't be reachable"
instance Choice p => Cochoice (Re p s t) where
unleft (Re p) = Re (p . left')
unright (Re p) = Re (p . right')
{-# INLINE unleft #-}
{-# INLINE unright #-}
instance Cochoice p => Choice (Re p s t) where
left' (Re p) = Re (p . unleft)
right' (Re p) = Re (p . unright)
{-# INLINE left' #-}
{-# INLINE right' #-}