module Optics.Prism
(
Prism
, Prism'
, prism
, prism'
, only
, nearly
, withPrism
, aside
, without
, below
, A_Prism
)
where
import Control.Monad
import Data.Bifunctor
import Data.Profunctor.Indexed
import Optics.Internal.Optic
type Prism s t a b = Optic A_Prism NoIx s t a b
type Prism' s a = Optic' A_Prism NoIx s a
prism :: (b -> t) -> (s -> Either t a) -> Prism s t a b
prism :: (b -> t) -> (s -> Either t a) -> Prism s t a b
prism b -> t
construct s -> Either t a
match = (forall (p :: * -> * -> * -> *) i.
Profunctor p =>
Optic_ A_Prism p i (Curry NoIx i) s t a b)
-> Prism s t a b
forall k (is :: IxList) s t a b.
(forall (p :: * -> * -> * -> *) i.
Profunctor p =>
Optic_ k p i (Curry is i) s t a b)
-> Optic k is s t a b
Optic ((forall (p :: * -> * -> * -> *) i.
Profunctor p =>
Optic_ A_Prism p i (Curry NoIx i) s t a b)
-> Prism s t a b)
-> (forall (p :: * -> * -> * -> *) i.
Profunctor p =>
Optic_ A_Prism p i (Curry NoIx i) s t a b)
-> Prism s t a b
forall a b. (a -> b) -> a -> b
$ (s -> Either t a)
-> (Either t b -> t) -> p i (Either t a) (Either t b) -> p i s t
forall (p :: * -> * -> * -> *) a b c d i.
Profunctor p =>
(a -> b) -> (c -> d) -> p i b c -> p i a d
dimap s -> Either t a
match ((t -> t) -> (b -> t) -> Either t b -> t
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either t -> t
forall a. a -> a
id b -> t
construct) (p i (Either t a) (Either t b) -> p i s t)
-> (p i a b -> p i (Either t a) (Either t b)) -> p i a b -> p i s t
forall b c a. (b -> c) -> (a -> b) -> a -> c
. p i a b -> p i (Either t a) (Either t b)
forall (p :: * -> * -> * -> *) i a b c.
Choice p =>
p i a b -> p i (Either c a) (Either c b)
right'
{-# INLINE prism #-}
prism' :: (b -> s) -> (s -> Maybe a) -> Prism s s a b
prism' :: (b -> s) -> (s -> Maybe a) -> Prism s s a b
prism' b -> s
bs s -> Maybe a
sma = (b -> s) -> (s -> Either s a) -> Prism s s a b
forall b t s a. (b -> t) -> (s -> Either t a) -> Prism s t a b
prism b -> s
bs (\s
s -> Either s a -> (a -> Either s a) -> Maybe a -> Either s a
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (s -> Either s a
forall a b. a -> Either a b
Left s
s) a -> Either s a
forall a b. b -> Either a b
Right (s -> Maybe a
sma s
s))
{-# INLINE prism' #-}
withPrism
:: Is k A_Prism
=> Optic k is s t a b
-> ((b -> t) -> (s -> Either t a) -> r)
-> r
withPrism :: Optic k is s t a b -> ((b -> t) -> (s -> Either t a) -> r) -> r
withPrism Optic k is s t a b
o (b -> t) -> (s -> Either t a) -> r
k = case Optic A_Prism is s t a b
-> Optic__ (Market a b) Any (Curry is Any) s t a b
forall (p :: * -> * -> * -> *) k (is :: IxList) s t a b i.
Profunctor p =>
Optic k is s t a b -> Optic_ k p i (Curry is i) s t a b
getOptic (Optic k is s t a b -> Optic A_Prism is s t a b
forall destKind srcKind (is :: IxList) s t a b.
Is srcKind destKind =>
Optic srcKind is s t a b -> Optic destKind is s t a b
castOptic @A_Prism Optic k is s t a b
o) ((b -> b) -> (a -> Either b a) -> Market a b Any a b
forall a b i s t. (b -> t) -> (s -> Either t a) -> Market a b i s t
Market b -> b
forall a. a -> a
id a -> Either b a
forall a b. b -> Either a b
Right) of
Market construct match -> (b -> t) -> (s -> Either t a) -> r
k b -> t
construct s -> Either t a
match
{-# INLINE withPrism #-}
aside :: Is k A_Prism => Optic k is s t a b -> Prism (e, s) (e, t) (e, a) (e, b)
aside :: Optic k is s t a b -> Prism (e, s) (e, t) (e, a) (e, b)
aside Optic k is s t a b
k =
Optic k is s t a b
-> ((b -> t)
-> (s -> Either t a) -> Prism (e, s) (e, t) (e, a) (e, b))
-> Prism (e, s) (e, t) (e, a) (e, b)
forall k (is :: IxList) s t a b r.
Is k A_Prism =>
Optic k is s t a b -> ((b -> t) -> (s -> Either t a) -> r) -> r
withPrism Optic k is s t a b
k (((b -> t)
-> (s -> Either t a) -> Prism (e, s) (e, t) (e, a) (e, b))
-> Prism (e, s) (e, t) (e, a) (e, b))
-> ((b -> t)
-> (s -> Either t a) -> Prism (e, s) (e, t) (e, a) (e, b))
-> Prism (e, s) (e, t) (e, a) (e, b)
forall a b. (a -> b) -> a -> b
$ \b -> t
bt s -> Either t a
seta ->
((e, b) -> (e, t))
-> ((e, s) -> Either (e, t) (e, a))
-> Prism (e, s) (e, t) (e, a) (e, b)
forall b t s a. (b -> t) -> (s -> Either t a) -> Prism s t a b
prism ((b -> t) -> (e, b) -> (e, t)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap b -> t
bt) (((e, s) -> Either (e, t) (e, a))
-> Prism (e, s) (e, t) (e, a) (e, b))
-> ((e, s) -> Either (e, t) (e, a))
-> Prism (e, s) (e, t) (e, a) (e, b)
forall a b. (a -> b) -> a -> b
$ \(e
e,s
s) ->
case s -> Either t a
seta s
s of
Left t
t -> (e, t) -> Either (e, t) (e, a)
forall a b. a -> Either a b
Left (e
e,t
t)
Right a
a -> (e, a) -> Either (e, t) (e, a)
forall a b. b -> Either a b
Right (e
e,a
a)
{-# INLINE aside #-}
without
:: (Is k A_Prism, Is l A_Prism)
=> Optic k is s t a b
-> Optic l is u v c d
-> Prism (Either s u) (Either t v) (Either a c) (Either b d)
without :: Optic k is s t a b
-> Optic l is u v c d
-> Prism (Either s u) (Either t v) (Either a c) (Either b d)
without Optic k is s t a b
k =
Optic k is s t a b
-> ((b -> t)
-> (s -> Either t a)
-> Optic l is u v c d
-> Prism (Either s u) (Either t v) (Either a c) (Either b d))
-> Optic l is u v c d
-> Prism (Either s u) (Either t v) (Either a c) (Either b d)
forall k (is :: IxList) s t a b r.
Is k A_Prism =>
Optic k is s t a b -> ((b -> t) -> (s -> Either t a) -> r) -> r
withPrism Optic k is s t a b
k (((b -> t)
-> (s -> Either t a)
-> Optic l is u v c d
-> Prism (Either s u) (Either t v) (Either a c) (Either b d))
-> Optic l is u v c d
-> Prism (Either s u) (Either t v) (Either a c) (Either b d))
-> ((b -> t)
-> (s -> Either t a)
-> Optic l is u v c d
-> Prism (Either s u) (Either t v) (Either a c) (Either b d))
-> Optic l is u v c d
-> Prism (Either s u) (Either t v) (Either a c) (Either b d)
forall a b. (a -> b) -> a -> b
$ \b -> t
bt s -> Either t a
seta Optic l is u v c d
k' ->
Optic l is u v c d
-> ((d -> v)
-> (u -> Either v c)
-> Prism (Either s u) (Either t v) (Either a c) (Either b d))
-> Prism (Either s u) (Either t v) (Either a c) (Either b d)
forall k (is :: IxList) s t a b r.
Is k A_Prism =>
Optic k is s t a b -> ((b -> t) -> (s -> Either t a) -> r) -> r
withPrism Optic l is u v c d
k' (((d -> v)
-> (u -> Either v c)
-> Prism (Either s u) (Either t v) (Either a c) (Either b d))
-> Prism (Either s u) (Either t v) (Either a c) (Either b d))
-> ((d -> v)
-> (u -> Either v c)
-> Prism (Either s u) (Either t v) (Either a c) (Either b d))
-> Prism (Either s u) (Either t v) (Either a c) (Either b d)
forall a b. (a -> b) -> a -> b
$ \d -> v
dv u -> Either v c
uevc ->
(Either b d -> Either t v)
-> (Either s u -> Either (Either t v) (Either a c))
-> Prism (Either s u) (Either t v) (Either a c) (Either b d)
forall b t s a. (b -> t) -> (s -> Either t a) -> Prism s t a b
prism ((b -> t) -> (d -> v) -> Either b d -> Either t v
forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap b -> t
bt d -> v
dv) ((Either s u -> Either (Either t v) (Either a c))
-> Prism (Either s u) (Either t v) (Either a c) (Either b d))
-> (Either s u -> Either (Either t v) (Either a c))
-> Prism (Either s u) (Either t v) (Either a c) (Either b d)
forall a b. (a -> b) -> a -> b
$ \Either s u
su ->
case Either s u
su of
Left s
s -> (t -> Either t v)
-> (a -> Either a c)
-> Either t a
-> Either (Either t v) (Either a c)
forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap t -> Either t v
forall a b. a -> Either a b
Left a -> Either a c
forall a b. a -> Either a b
Left (s -> Either t a
seta s
s)
Right u
u -> (v -> Either t v)
-> (c -> Either a c)
-> Either v c
-> Either (Either t v) (Either a c)
forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap v -> Either t v
forall a b. b -> Either a b
Right c -> Either a c
forall a b. b -> Either a b
Right (u -> Either v c
uevc u
u)
{-# INLINE without #-}
below
:: (Is k A_Prism, Traversable f)
=> Optic' k is s a
-> Prism' (f s) (f a)
below :: Optic' k is s a -> Prism' (f s) (f a)
below Optic' k is s a
k =
Optic' k is s a
-> ((a -> s) -> (s -> Either s a) -> Prism' (f s) (f a))
-> Prism' (f s) (f a)
forall k (is :: IxList) s t a b r.
Is k A_Prism =>
Optic k is s t a b -> ((b -> t) -> (s -> Either t a) -> r) -> r
withPrism Optic' k is s a
k (((a -> s) -> (s -> Either s a) -> Prism' (f s) (f a))
-> Prism' (f s) (f a))
-> ((a -> s) -> (s -> Either s a) -> Prism' (f s) (f a))
-> Prism' (f s) (f a)
forall a b. (a -> b) -> a -> b
$ \a -> s
bt s -> Either s a
seta ->
(f a -> f s) -> (f s -> Either (f s) (f a)) -> Prism' (f s) (f a)
forall b t s a. (b -> t) -> (s -> Either t a) -> Prism s t a b
prism ((a -> s) -> f a -> f s
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> s
bt) ((f s -> Either (f s) (f a)) -> Prism' (f s) (f a))
-> (f s -> Either (f s) (f a)) -> Prism' (f s) (f a)
forall a b. (a -> b) -> a -> b
$ \f s
s ->
case (s -> Either s a) -> f s -> Either s (f a)
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse s -> Either s a
seta f s
s of
Left s
_ -> f s -> Either (f s) (f a)
forall a b. a -> Either a b
Left f s
s
Right f a
t -> f a -> Either (f s) (f a)
forall a b. b -> Either a b
Right f a
t
{-# INLINE below #-}
only :: Eq a => a -> Prism' a ()
only :: a -> Prism' a ()
only a
a = (() -> a) -> (a -> Maybe ()) -> Prism' a ()
forall b s a. (b -> s) -> (s -> Maybe a) -> Prism s s a b
prism' (\() -> a
a) ((a -> Maybe ()) -> Prism' a ()) -> (a -> Maybe ()) -> Prism' a ()
forall a b. (a -> b) -> a -> b
$ Bool -> Maybe ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Bool -> Maybe ()) -> (a -> Bool) -> a -> Maybe ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a
a a -> a -> Bool
forall a. Eq a => a -> a -> Bool
==)
{-# INLINE only #-}
nearly :: a -> (a -> Bool) -> Prism' a ()
nearly :: a -> (a -> Bool) -> Prism' a ()
nearly a
a a -> Bool
p = (() -> a) -> (a -> Maybe ()) -> Prism' a ()
forall b s a. (b -> s) -> (s -> Maybe a) -> Prism s s a b
prism' (\() -> a
a) ((a -> Maybe ()) -> Prism' a ()) -> (a -> Maybe ()) -> Prism' a ()
forall a b. (a -> b) -> a -> b
$ Bool -> Maybe ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Bool -> Maybe ()) -> (a -> Bool) -> a -> Maybe ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Bool
p
{-# INLINE nearly #-}