{-# LANGUAGE ScopedTypeVariables #-}
-----------------------------------------------------------------------------

-- |

-- Module      :  Control.Lens.Internal.Prism

-- Copyright   :  (C) 2012-2016 Edward Kmett

-- License     :  BSD-style (see the file LICENSE)

-- Maintainer  :  Edward Kmett <ekmett@gmail.com>

-- Stability   :  experimental

-- Portability :  non-portable

--

----------------------------------------------------------------------------

module Control.Lens.Internal.Prism
  ( Market(..)
  , Market'
  ) where

import Prelude ()

import Control.Lens.Internal.Prelude

------------------------------------------------------------------------------

-- Prism: Market

------------------------------------------------------------------------------


-- | This type is used internally by the 'Control.Lens.Prism.Prism' code to

-- provide efficient access to the two parts of a 'Prism'.

data Market a b s t = Market (b -> t) (s -> Either t a)

-- | @type 'Market'' a s t = 'Market' a a s t@

type Market' a = Market a a

instance Functor (Market a b s) where
  fmap :: forall a b. (a -> b) -> Market a b s a -> Market a b s b
fmap a -> b
f (Market b -> a
bt s -> Either a a
seta) = forall a b s t. (b -> t) -> (s -> Either t a) -> Market a b s t
Market (a -> b
f forall b c a. (b -> c) -> (a -> b) -> a -> c
. b -> a
bt) (forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (forall a b. a -> Either a b
Left forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> b
f) forall a b. b -> Either a b
Right forall b c a. (b -> c) -> (a -> b) -> a -> c
. s -> Either a a
seta)
  {-# INLINE fmap #-}

instance Profunctor (Market a b) where
  dimap :: forall a b c d.
(a -> b) -> (c -> d) -> Market a b b c -> Market a b a d
dimap a -> b
f c -> d
g (Market b -> c
bt b -> Either c a
seta) = forall a b s t. (b -> t) -> (s -> Either t a) -> Market a b s t
Market (c -> d
g forall b c a. (b -> c) -> (a -> b) -> a -> c
. b -> c
bt) (forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (forall a b. a -> Either a b
Left forall b c a. (b -> c) -> (a -> b) -> a -> c
. c -> d
g) forall a b. b -> Either a b
Right forall b c a. (b -> c) -> (a -> b) -> a -> c
. b -> Either c a
seta forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> b
f)
  {-# INLINE dimap #-}
  lmap :: forall a b c. (a -> b) -> Market a b b c -> Market a b a c
lmap a -> b
f (Market b -> c
bt b -> Either c a
seta) = forall a b s t. (b -> t) -> (s -> Either t a) -> Market a b s t
Market b -> c
bt (b -> Either c a
seta forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> b
f)
  {-# INLINE lmap #-}
  rmap :: forall b c a. (b -> c) -> Market a b a b -> Market a b a c
rmap b -> c
f (Market b -> b
bt a -> Either b a
seta) = forall a b s t. (b -> t) -> (s -> Either t a) -> Market a b s t
Market (b -> c
f forall b c a. (b -> c) -> (a -> b) -> a -> c
. b -> b
bt) (forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (forall a b. a -> Either a b
Left forall b c a. (b -> c) -> (a -> b) -> a -> c
. b -> c
f) forall a b. b -> Either a b
Right forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Either b a
seta)
  {-# INLINE rmap #-}

  #. :: forall a b c (q :: * -> * -> *).
Coercible c b =>
q b c -> Market a b a b -> Market a b a c
(#.) q b c
_ = coerce :: forall a b. Coercible a b => a -> b
coerce
  {-# INLINE (#.) #-}
  .# :: forall a b c (q :: * -> * -> *).
Coercible b a =>
Market a b b c -> q a b -> Market a b a c
(.#) Market a b b c
p q a b
_ = coerce :: forall a b. Coercible a b => a -> b
coerce Market a b b c
p
  {-# INLINE (.#) #-}

instance Choice (Market a b) where
  left' :: forall a b c.
Market a b a b -> Market a b (Either a c) (Either b c)
left' (Market b -> b
bt a -> Either b a
seta) = forall a b s t. (b -> t) -> (s -> Either t a) -> Market a b s t
Market (forall a b. a -> Either a b
Left forall b c a. (b -> c) -> (a -> b) -> a -> c
. b -> b
bt) forall a b. (a -> b) -> a -> b
$ \Either a c
sc -> case Either a c
sc of
    Left a
s -> case a -> Either b a
seta a
s of
      Left b
t -> forall a b. a -> Either a b
Left (forall a b. a -> Either a b
Left b
t)
      Right a
a -> forall a b. b -> Either a b
Right a
a
    Right c
c -> forall a b. a -> Either a b
Left (forall a b. b -> Either a b
Right c
c)
  {-# INLINE left' #-}
  right' :: forall a b c.
Market a b a b -> Market a b (Either c a) (Either c b)
right' (Market b -> b
bt a -> Either b a
seta) = forall a b s t. (b -> t) -> (s -> Either t a) -> Market a b s t
Market (forall a b. b -> Either a b
Right forall b c a. (b -> c) -> (a -> b) -> a -> c
. b -> b
bt) forall a b. (a -> b) -> a -> b
$ \Either c a
cs -> case Either c a
cs of
    Left c
c -> forall a b. a -> Either a b
Left (forall a b. a -> Either a b
Left c
c)
    Right a
s -> case a -> Either b a
seta a
s of
      Left b
t -> forall a b. a -> Either a b
Left (forall a b. b -> Either a b
Right b
t)
      Right a
a -> forall a b. b -> Either a b
Right a
a
  {-# INLINE right' #-}