{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE QuantifiedConstraints #-}
module Proton.Getter where

import Data.Profunctor
import Data.Profunctor.Phantom
import Proton.Types

type Getter s t a b = forall p. Phantom p => p a b -> p s t

to' :: (s -> a) -> Getter s t a b
to' :: (s -> a) -> Getter s t a b
to' f :: s -> a
f = p s b -> p s t
forall (p :: * -> * -> *) a x y. Phantom p => p a x -> p a y
phantom (p s b -> p s t) -> (p a b -> p s b) -> p a b -> p s t
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (s -> a) -> p a b -> p s b
forall (p :: * -> * -> *) a b c.
Profunctor p =>
(a -> b) -> p b c -> p a c
lmap s -> a
f

-- Getter without Phantom requirement, may be useful with Grids/Grates
to :: Profunctor p => (s -> a) -> Optic p s b a b
to :: (s -> a) -> Optic p s b a b
to f :: s -> a
f = (s -> a) -> Optic p s b a b
forall (p :: * -> * -> *) a b c.
Profunctor p =>
(a -> b) -> p b c -> p a c
lmap s -> a
f

view :: Optic (Forget a) s t a b -> s -> a
view :: Optic (Forget a) s t a b -> s -> a
view g :: Optic (Forget a) s t a b
g = Forget a s t -> s -> a
forall r a b. Forget r a b -> a -> r
runForget (Forget a s t -> s -> a)
-> Optic (Forget a) s t a b -> Forget a a b -> s -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Optic (Forget a) s t a b
g (Forget a a b -> s -> a) -> Forget a a b -> s -> a
forall a b. (a -> b) -> a -> b
$ (a -> a) -> Forget a a b
forall r a b. (a -> r) -> Forget r a b
Forget a -> a
forall a. a -> a
id

views :: Optic (Forget a) s t a b -> (a -> a') -> s -> a'
views :: Optic (Forget a) s t a b -> (a -> a') -> s -> a'
views g :: Optic (Forget a) s t a b
g f :: a -> a'
f = a -> a'
f (a -> a') -> (s -> a) -> s -> a'
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Optic (Forget a) s t a b -> s -> a
forall a s t b. Optic (Forget a) s t a b -> s -> a
view Optic (Forget a) s t a b
g

like :: a -> Getter s t a b
like :: a -> Getter s t a b
like = (s -> a) -> p a b -> p s t
forall s a t b. (s -> a) -> Getter s t a b
to' ((s -> a) -> p a b -> p s t)
-> (a -> s -> a) -> a -> p a b -> p s t
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> s -> a
forall a b. a -> b -> a
const

infixl 8 ^.
(^.) ::  s -> Optic (Forget a) s t a b -> a
^. :: s -> Optic (Forget a) s t a b -> a
(^.) = (Optic (Forget a) s t a b -> s -> a)
-> s -> Optic (Forget a) s t a b -> a
forall a b c. (a -> b -> c) -> b -> a -> c
flip Optic (Forget a) s t a b -> s -> a
forall a s t b. Optic (Forget a) s t a b -> s -> a
view