    -- |
    -- Module: Optics.Getter
    -- Description: A function considered as an 'Optic'.
    --
    -- A 'Getter' is simply a function considered as an 'Optic'.
    --
    -- Given a function @f :: S -> A@, we can convert it into a
    -- @'Getter' S A@ using 'to', and convert back to a function using 'view'.
    --
    -- This is typically useful not when you have functions/'Getter's
    -- alone, but when you are composing multiple 'Optic's to produce a
    -- 'Getter'.
    --
    module Optics.Getter
      (
      -- * Formation
       Getter

      -- * Introduction
      , to

      -- * Elimination
      , view
      , views

      -- * Computation
      -- |
      --
      -- @
      -- 'view' ('to' f) ≡ f
      -- @

      -- * Well-formedness
      -- | A 'Getter' is not subject to any laws.

      -- * Subtyping
      , A_Getter
      -- | <<diagrams/Getter.png Getter in the optics hierarchy>>
      )
      where

    import Data.Profunctor.Indexed

    import Optics.Internal.Bi
    import Optics.Internal.Optic

    -- | Type synonym for a getter.
    type Getter s a = Optic' A_Getter NoIx s a

    -- | View the value pointed to by a getter.
    --
    -- If you want to 'view' a type-modifying optic that is insufficiently
    -- polymorphic to be type-preserving, use 'Optics.ReadOnly.getting'.
    --
    view :: Is k A_Getter => Optic' k is s a -> s -> a
    view :: forall (k :: OpticKind) (is :: IxList) (s :: OpticKind)
           (a :: OpticKind).
    Is k A_Getter =>
    Optic' k is s a -> s -> a
    view Optic' k is s a
    o = Optic' k is s a -> (a -> a) -> s -> a
    forall (k :: OpticKind) (is :: IxList) (s :: OpticKind)
           (a :: OpticKind) (r :: OpticKind).
    Is k A_Getter =>
    Optic' k is s a -> (a -> r) -> s -> r
    views Optic' k is s a
    o a -> a
    forall (a :: OpticKind). a -> a
    id
    {-# INLINE view #-}

    -- | View the function of the value pointed to by a getter.
    views :: Is k A_Getter => Optic' k is s a -> (a -> r) -> s -> r
    views :: forall (k :: OpticKind) (is :: IxList) (s :: OpticKind)
           (a :: OpticKind) (r :: OpticKind).
    Is k A_Getter =>
    Optic' k is s a -> (a -> r) -> s -> r
    views Optic' k is s a
    o = \a -> r
    f -> Forget r (Curry is (ZonkAny 0)) s s -> s -> r
    forall (r :: OpticKind) (i :: OpticKind) (a :: OpticKind)
           (b :: OpticKind).
    Forget r i a b -> a -> r
    runForget (Forget r (Curry is (ZonkAny 0)) s s -> s -> r)
    -> Forget r (Curry is (ZonkAny 0)) s s -> s -> r
    forall a b. (a -> b) -> a -> b
    $ Optic A_Getter is s s a a
    -> Optic_
         A_Getter (Forget r) (ZonkAny 0) (Curry is (ZonkAny 0)) s s a a
    forall (p :: OpticKind -> OpticKind -> OpticKind -> OpticKind)
           (k :: OpticKind) (is :: IxList) (s :: OpticKind) (t :: OpticKind)
           (a :: OpticKind) (b :: OpticKind) (i :: OpticKind).
    Profunctor p =>
    Optic k is s t a b -> Optic_ k p i (Curry is i) s t a b
    getOptic (forall (destKind :: OpticKind) (srcKind :: OpticKind)
           (is :: IxList) (s :: OpticKind) (t :: OpticKind) (a :: OpticKind)
           (b :: OpticKind).
    Is srcKind destKind =>
    Optic srcKind is s t a b -> Optic destKind is s t a b
    castOptic @A_Getter Optic' k is s a
    o) ((a -> r) -> Forget r (ZonkAny 0) a a
    forall (r :: OpticKind) (i :: OpticKind) (a :: OpticKind)
           (b :: OpticKind).
    (a -> r) -> Forget r i a b
    Forget a -> r
    f)
    {-# INLINE views #-}

    -- | Build a getter from a function.
    to :: (s -> a) -> Getter s a
    to :: forall (s :: OpticKind) (a :: OpticKind). (s -> a) -> Getter s a
    to s -> a
    f = (forall (p :: OpticKind -> OpticKind -> OpticKind -> OpticKind)
            (i :: OpticKind).
     Profunctor p =>
     Optic_ A_Getter p i (Curry NoIx i) s s a a)
    -> Optic A_Getter NoIx s s a a
    forall (k :: OpticKind) (is :: IxList) (s :: OpticKind)
           (t :: OpticKind) (a :: OpticKind) (b :: OpticKind).
    (forall (p :: OpticKind -> OpticKind -> OpticKind -> OpticKind)
            (i :: OpticKind).
     Profunctor p =>
     Optic_ k p i (Curry is i) s t a b)
    -> Optic k is s t a b
    Optic ((s -> a) -> p i a s -> p i s s
    forall (a :: OpticKind) (b :: OpticKind) (i :: OpticKind)
           (c :: OpticKind).
    (a -> b) -> p i b c -> p i a c
    forall (p :: OpticKind -> OpticKind -> OpticKind -> OpticKind)
           (a :: OpticKind) (b :: OpticKind) (i :: OpticKind)
           (c :: OpticKind).
    Profunctor p =>
    (a -> b) -> p i b c -> p i a c
    lmap s -> a
    f (p i a s -> p i s s) -> (p i a a -> p i a s) -> p i a a -> p i s s
    forall (b :: OpticKind) (c :: OpticKind) (a :: OpticKind).
    (b -> c) -> (a -> b) -> a -> c
    . p i a a -> p i a s
    forall (p :: OpticKind -> OpticKind -> OpticKind -> OpticKind)
           (i :: OpticKind) (c :: OpticKind) (a :: OpticKind)
           (b :: OpticKind).
    (Profunctor p, Bicontravariant p) =>
    p i c a -> p i c b
    rphantom)
    {-# INLINE to #-}