{-# LANGUAGE EmptyCase #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE Rank2Types #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE PolyKinds #-}
-----------------------------------------------------------------------------
-- |
-- Module      :  GHC.Generics.Lens
-- Copyright   :  (C) 2012-16 Edward Kmett
-- License     :  BSD-style (see the file LICENSE)
-- Maintainer  :  Edward Kmett <ekmett@gmail.com>
-- Stability   :  experimental
-- Portability :  GHC
--
-- Note: @GHC.Generics@ exports a number of names that collide with @Control.Lens@.
--
-- You can use hiding or imports to mitigate this to an extent, and the following imports,
-- represent a fair compromise for user code:
--
-- > import Control.Lens hiding (Rep)
-- > import GHC.Generics hiding (from, to)
--
-- You can use 'generic' to replace 'GHC.Generics.from' and 'GHC.Generics.to' from @GHC.Generics@,
-- and probably won't be explicitly referencing 'Control.Lens.Representable.Rep' from @Control.Lens@
-- in code that uses generics.
--
-- This module provides compatibility with older GHC versions by using the
-- <http://hackage.haskell.org/package/generic-deriving generic-deriving>
-- package.
----------------------------------------------------------------------------
module GHC.Generics.Lens
  (
    generic
  , generic1
  , _V1
  , _U1
  , _Par1
  , _Rec1
  , _K1
  , _M1
  , _L1
  , _R1
  , _UAddr
  , _UChar
  , _UDouble
  , _UFloat
  , _UInt
  , _UWord
  ) where

import           Control.Lens
import           GHC.Exts (Char(..), Double(..), Float(..),
                           Int(..), Ptr(..), Word(..))
import qualified GHC.Generics as Generic
import           GHC.Generics hiding (from, to)

-- $setup
-- >>> :set -XNoOverloadedStrings
-- >>> import Control.Lens

-- | Convert from the data type to its representation (or back)
--
-- >>> "hello"^.generic.from generic :: String
-- "hello"
generic :: (Generic a, Generic b) => Iso a b (Rep a g) (Rep b h)
generic :: Iso a b (Rep a g) (Rep b h)
generic = (a -> Rep a g) -> (Rep b h -> b) -> Iso a b (Rep a g) (Rep b h)
forall s a b t. (s -> a) -> (b -> t) -> Iso s t a b
iso a -> Rep a g
forall a x. Generic a => a -> Rep a x
Generic.from Rep b h -> b
forall a x. Generic a => Rep a x -> a
Generic.to
{-# INLINE generic #-}

-- | Convert from the data type to its representation (or back)
generic1 :: (Generic1 f, Generic1 g) => Iso (f a) (g b) (Rep1 f a) (Rep1 g b)
generic1 :: Iso (f a) (g b) (Rep1 f a) (Rep1 g b)
generic1 = (f a -> Rep1 f a)
-> (Rep1 g b -> g b) -> Iso (f a) (g b) (Rep1 f a) (Rep1 g b)
forall s a b t. (s -> a) -> (b -> t) -> Iso s t a b
iso f a -> Rep1 f a
forall k (f :: k -> *) (a :: k). Generic1 f => f a -> Rep1 f a
from1 Rep1 g b -> g b
forall k (f :: k -> *) (a :: k). Generic1 f => Rep1 f a -> f a
to1
{-# INLINE generic1 #-}

_V1 :: Over p f (V1 s) (V1 t) a b
_V1 :: Over p f (V1 s) (V1 t) a b
_V1 p a (f b)
_ = V1 s -> f (V1 t)
\case
{-# INLINE _V1 #-}

_U1 :: Iso (U1 p) (U1 q) () ()
_U1 :: p () (f ()) -> p (U1 p) (f (U1 q))
_U1 = (U1 p -> ()) -> (() -> U1 q) -> Iso (U1 p) (U1 q) () ()
forall s a b t. (s -> a) -> (b -> t) -> Iso s t a b
iso (() -> U1 p -> ()
forall a b. a -> b -> a
const ()) (U1 q -> () -> U1 q
forall a b. a -> b -> a
const U1 q
forall k (p :: k). U1 p
U1)
{-# INLINE _U1 #-}

_Par1 :: Iso (Par1 p) (Par1 q) p q
_Par1 :: p p (f q) -> p (Par1 p) (f (Par1 q))
_Par1 = p p (f q) -> p (Par1 p) (f (Par1 q))
forall s t a b. (Coercible s a, Coercible t b) => Iso s t a b
coerced
{-# INLINE _Par1 #-}

_Rec1 :: Iso (Rec1 f p) (Rec1 g q) (f p) (g q)
_Rec1 :: p (f p) (f (g q)) -> p (Rec1 f p) (f (Rec1 g q))
_Rec1 = p (f p) (f (g q)) -> p (Rec1 f p) (f (Rec1 g q))
forall s t a b. (Coercible s a, Coercible t b) => Iso s t a b
coerced
{-# INLINE _Rec1 #-}

_K1 :: Iso (K1 i c p) (K1 j d q) c d
_K1 :: p c (f d) -> p (K1 i c p) (f (K1 j d q))
_K1 = p c (f d) -> p (K1 i c p) (f (K1 j d q))
forall s t a b. (Coercible s a, Coercible t b) => Iso s t a b
coerced
{-# INLINE _K1 #-}

_M1 :: Iso (M1 i c f p) (M1 j d g q) (f p) (g q)
_M1 :: p (f p) (f (g q)) -> p (M1 i c f p) (f (M1 j d g q))
_M1 = p (f p) (f (g q)) -> p (M1 i c f p) (f (M1 j d g q))
forall s t a b. (Coercible s a, Coercible t b) => Iso s t a b
coerced
{-# INLINE _M1 #-}

_L1 :: Prism' ((f :+: g) a) (f a)
_L1 :: p (f a) (f (f a)) -> p ((:+:) f g a) (f ((:+:) f g a))
_L1 = (f a -> (:+:) f g a)
-> ((:+:) f g a -> Either ((:+:) f g a) (f a))
-> Prism ((:+:) f g a) ((:+:) f g a) (f a) (f a)
forall b t s a. (b -> t) -> (s -> Either t a) -> Prism s t a b
prism f a -> (:+:) f g a
forall k (f :: k -> *) (p :: k) (g :: k -> *). f p -> (:+:) f g p
remitter (:+:) f g a -> Either ((:+:) f g a) (f a)
forall k (f :: k -> *) (g :: k -> *) (p :: k).
(:+:) f g p -> Either ((:+:) f g p) (f p)
reviewer
  where
  remitter :: f p -> (:+:) f g p
remitter = f p -> (:+:) f g p
forall k (f :: k -> *) (g :: k -> *) (p :: k). f p -> (:+:) f g p
L1
  reviewer :: (:+:) f g p -> Either ((:+:) f g p) (f p)
reviewer (L1 f p
l) = f p -> Either ((:+:) f g p) (f p)
forall a b. b -> Either a b
Right f p
l
  reviewer (:+:) f g p
x = (:+:) f g p -> Either ((:+:) f g p) (f p)
forall a b. a -> Either a b
Left (:+:) f g p
x
{-# INLINE _L1 #-}

-- | You can access fields of `data (f :*: g) p` by using its `Field1` and
-- `Field2` instances.

_R1 :: Prism' ((f :+: g) a) (g a)
_R1 :: p (g a) (f (g a)) -> p ((:+:) f g a) (f ((:+:) f g a))
_R1 = (g a -> (:+:) f g a)
-> ((:+:) f g a -> Either ((:+:) f g a) (g a))
-> Prism ((:+:) f g a) ((:+:) f g a) (g a) (g a)
forall b t s a. (b -> t) -> (s -> Either t a) -> Prism s t a b
prism g a -> (:+:) f g a
forall k (g :: k -> *) (p :: k) (f :: k -> *). g p -> (:+:) f g p
remitter (:+:) f g a -> Either ((:+:) f g a) (g a)
forall k (f :: k -> *) (g :: k -> *) (p :: k).
(:+:) f g p -> Either ((:+:) f g p) (g p)
reviewer
  where
  remitter :: g p -> (:+:) f g p
remitter = g p -> (:+:) f g p
forall k (f :: k -> *) (g :: k -> *) (p :: k). g p -> (:+:) f g p
R1
  reviewer :: (:+:) f g p -> Either ((:+:) f g p) (g p)
reviewer (R1 g p
l) = g p -> Either ((:+:) f g p) (g p)
forall a b. b -> Either a b
Right g p
l
  reviewer (:+:) f g p
x = (:+:) f g p -> Either ((:+:) f g p) (g p)
forall a b. a -> Either a b
Left (:+:) f g p
x
{-# INLINE _R1 #-}

_UAddr :: Iso (UAddr p) (UAddr q) (Ptr c) (Ptr d)
_UAddr :: p (Ptr c) (f (Ptr d)) -> p (UAddr p) (f (UAddr q))
_UAddr = (UAddr p -> Ptr c)
-> (Ptr d -> UAddr q) -> Iso (UAddr p) (UAddr q) (Ptr c) (Ptr d)
forall s a b t. (s -> a) -> (b -> t) -> Iso s t a b
iso UAddr p -> Ptr c
forall k (p :: k) a. URec (Ptr ()) p -> Ptr a
remitter Ptr d -> UAddr q
forall k a (p :: k). Ptr a -> URec (Ptr ()) p
reviewer
  where
  remitter :: URec (Ptr ()) p -> Ptr a
remitter (UAddr a) = Addr# -> Ptr a
forall a. Addr# -> Ptr a
Ptr Addr#
a
  reviewer :: Ptr a -> URec (Ptr ()) p
reviewer (Ptr Addr#
a) = Addr# -> URec (Ptr ()) p
forall k (p :: k). Addr# -> URec (Ptr ()) p
UAddr Addr#
a
{-# INLINE _UAddr #-}

_UChar :: Iso (UChar p) (UChar q) Char Char
_UChar :: p Char (f Char) -> p (UChar p) (f (UChar q))
_UChar = (UChar p -> Char)
-> (Char -> UChar q) -> Iso (UChar p) (UChar q) Char Char
forall s a b t. (s -> a) -> (b -> t) -> Iso s t a b
iso UChar p -> Char
forall k (p :: k). URec Char p -> Char
remitter Char -> UChar q
forall k (p :: k). Char -> URec Char p
reviewer
  where
  remitter :: URec Char p -> Char
remitter (UChar c) = Char# -> Char
C# Char#
c
  reviewer :: Char -> URec Char p
reviewer (C# Char#
c) = Char# -> URec Char p
forall k (p :: k). Char# -> URec Char p
UChar Char#
c
{-# INLINE _UChar #-}

_UDouble :: Iso (UDouble p) (UDouble q) Double Double
_UDouble :: p Double (f Double) -> p (UDouble p) (f (UDouble q))
_UDouble = (UDouble p -> Double)
-> (Double -> UDouble q)
-> Iso (UDouble p) (UDouble q) Double Double
forall s a b t. (s -> a) -> (b -> t) -> Iso s t a b
iso UDouble p -> Double
forall k (p :: k). URec Double p -> Double
remitter Double -> UDouble q
forall k (p :: k). Double -> URec Double p
reviewer
  where
  remitter :: URec Double p -> Double
remitter (UDouble d) = Double# -> Double
D# Double#
d
  reviewer :: Double -> URec Double p
reviewer (D# Double#
d) = Double# -> URec Double p
forall k (p :: k). Double# -> URec Double p
UDouble Double#
d
{-# INLINE _UDouble #-}

_UFloat :: Iso (UFloat p) (UFloat q) Float Float
_UFloat :: p Float (f Float) -> p (UFloat p) (f (UFloat q))
_UFloat = (UFloat p -> Float)
-> (Float -> UFloat q) -> Iso (UFloat p) (UFloat q) Float Float
forall s a b t. (s -> a) -> (b -> t) -> Iso s t a b
iso UFloat p -> Float
forall k (p :: k). URec Float p -> Float
remitter Float -> UFloat q
forall k (p :: k). Float -> URec Float p
reviewer
  where
  remitter :: URec Float p -> Float
remitter (UFloat f) = Float# -> Float
F# Float#
f
  reviewer :: Float -> URec Float p
reviewer (F# Float#
f) = Float# -> URec Float p
forall k (p :: k). Float# -> URec Float p
UFloat Float#
f
{-# INLINE _UFloat #-}

_UInt :: Iso (UInt p) (UInt q) Int Int
_UInt :: p Int (f Int) -> p (UInt p) (f (UInt q))
_UInt = (UInt p -> Int) -> (Int -> UInt q) -> Iso (UInt p) (UInt q) Int Int
forall s a b t. (s -> a) -> (b -> t) -> Iso s t a b
iso UInt p -> Int
forall k (p :: k). URec Int p -> Int
remitter Int -> UInt q
forall k (p :: k). Int -> URec Int p
reviewer
  where
  remitter :: URec Int p -> Int
remitter (UInt i) = Int# -> Int
I# Int#
i
  reviewer :: Int -> URec Int p
reviewer (I# Int#
i) = Int# -> URec Int p
forall k (p :: k). Int# -> URec Int p
UInt Int#
i
{-# INLINE _UInt #-}

_UWord :: Iso (UWord p) (UWord q) Word Word
_UWord :: p Word (f Word) -> p (UWord p) (f (UWord q))
_UWord = (UWord p -> Word)
-> (Word -> UWord q) -> Iso (UWord p) (UWord q) Word Word
forall s a b t. (s -> a) -> (b -> t) -> Iso s t a b
iso UWord p -> Word
forall k (p :: k). URec Word p -> Word
remitter Word -> UWord q
forall k (p :: k). Word -> URec Word p
reviewer
  where
  remitter :: URec Word p -> Word
remitter (UWord w) = Word# -> Word
W# Word#
w
  reviewer :: Word -> URec Word p
reviewer (W# Word#
w) = Word# -> URec Word p
forall k (p :: k). Word# -> URec Word p
UWord Word#
w
{-# INLINE _UWord #-}