module Lens.Explicit.Core where
import Prelude hiding (id, (.))
import Control.Category
import Control.Monad ((>=>))
import Control.Applicative (Const(..))
import Control.Arrow ((+++))
import Data.Functor.Identity
import GHC.Exts (Constraint)
type Optic c s t a b = OpticC c (a,b) (s,t)
data OpticC c x y where
Equality :: OpticC c q q
OpticC :: c s t a b -> Optic c s t a b
class (Category (OpticC c)) => Optical c where
type OptDens c (ζ :: * -> * -> * -> * -> *) :: Constraint
cloneOptic :: OptDens c ζ => c s t a b -> ζ s t a b
(∘) :: c x y s t -> c s t a b -> c x y a b
instance (Optical c) => Category (OpticC c) where
id = Equality
Equality . f = f
f . Equality = f
OpticC f . OpticC g = OpticC $ f ∘ g
data IsoTrait s t a b = Iso (s -> a) (b -> t)
instance Category (OpticC IsoTrait) where
id = Equality
Equality . f = f
f . Equality = f
OpticC (Iso g γ) . OpticC (Iso f φ) = OpticC $ Iso (f . g) (γ . φ)
type AnIso s t a b = Optic IsoTrait s t a b
type Iso s t a b = ∀ c . FromIso c => Optic c s t a b
class FromIso c where
iso :: (s -> a) -> (b -> t) -> c s t a b
instance FromIso IsoTrait where
iso = Iso
instance FromIso GetterTrait where
iso f _ = Getter f
instance FromIso ReviewTrait where
iso _ φ = Review φ
instance FromIso LensTrait where
iso f φ = Lens f (\_ b -> φ b)
instance FromIso PrismTrait where
iso f φ = Prism φ (Right . f)
instance FromIso SetterTrait where
iso f φ = Setter $ \u -> φ . u . f
instance FromIso FoldTrait where
iso f _ = Fold (\t -> t . f)
instance FromIso TraversalTrait where
iso f φ = Traversal (\t -> fmap φ . t . f)
data LensTrait s t a b = Lens (s -> a) (s -> b -> t)
instance Optical LensTrait where
type OptDens LensTrait ζ = FromLens ζ
cloneOptic (Lens f φ) = lens f φ
Lens g γ ∘ Lens f φ = Lens (f . g) (\s b -> γ s $ φ (g s) b)
type ALens s t a b = Optic LensTrait s t a b
type Lens s t a b = ∀ c . FromLens c => Optic c s t a b
class FromIso c => FromLens c where
lens :: (s -> a) -> (s -> b -> t) -> c s t a b
instance FromLens GetterTrait where
lens f _ = Getter f
instance FromLens LensTrait where
lens = Lens
instance FromLens TraversalTrait where
lens f φ = Traversal (\τ s -> fmap (φ s) . τ $ f s)
instance FromLens FoldTrait where
lens f _ = Fold (\τ -> τ . f)
instance FromLens SetterTrait where
lens f φ = Setter (\τ s -> φ s . τ $ f s)
data PrismTrait s t a b = Prism (b -> t) (s -> Either t a)
instance Optical PrismTrait where
type OptDens PrismTrait ζ = FromPrism ζ
cloneOptic (Prism f φ) = prism f φ
Prism γ g ∘ Prism φ f = Prism (γ . φ) (g >=> (γ+++id) . f)
type APrism s t a b = Optic PrismTrait s t a b
type Prism s t a b = ∀ c . FromPrism c => Optic c s t a b
class FromIso c => FromPrism c where
prism :: (b -> t) -> (s -> Either t a) -> c s t a b
instance FromPrism PrismTrait where
prism = Prism
instance FromPrism TraversalTrait where
prism φ f = Traversal (\τ -> either pure (fmap φ . τ) . f)
instance FromPrism FoldTrait where
prism φ f = Fold (\τ -> either (const mempty) τ . f)
instance FromPrism SetterTrait where
prism φ f = Setter (\τ -> either id (φ . τ) . f)
instance FromPrism ReviewTrait where
prism φ _ = Review φ
data GetterTrait s t a b = Getter (s -> a)
instance Optical GetterTrait where
type OptDens GetterTrait ζ = FromGetter ζ
cloneOptic (Getter f) = to f
Getter g ∘ Getter f = Getter (f . g)
type AGetter s a = Optic GetterTrait s s a a
type Getter s t a b = ∀ c . FromGetter c => Optic c s t a b
class FromLens c => FromGetter c where
to :: (s -> a) -> c s t a b
instance FromGetter GetterTrait where
to = Getter
instance FromGetter FoldTrait where
to f = Fold (\t -> t . f)
data ReviewTrait s t a b = Review (b -> t)
instance Category (OpticC ReviewTrait) where
id = Equality
Equality . f = f
f . Equality = f
OpticC (Review η) . OpticC (Review θ) = OpticC $ Review (η . θ)
type AReview b t = Optic ReviewTrait t t b b
type Review s t a b = ∀ c . FromReview c => Optic c s t a b
class FromPrism c => FromReview c where
unto :: (b -> t) -> c s t a b
instance FromReview ReviewTrait where
unto = Review
data TraversalTrait s t a b = Traversal (∀ f . Applicative f => (a -> f b) -> s -> f t)
instance Optical TraversalTrait where
type OptDens TraversalTrait ζ = FromTraversal ζ
cloneOptic (Traversal η) = traversed η
Traversal η ∘ Traversal θ = Traversal (η . θ)
type ATraversal s t a b = Optic TraversalTrait s t a b
type Traversal s t a b = ∀ c . FromTraversal c => Optic c s t a b
class (FromLens c, FromPrism c) => FromTraversal c where
traversed :: (∀ f . Applicative f => (a -> f b) -> s -> f t) -> c s t a b
instance FromTraversal TraversalTrait where
traversed = Traversal
instance FromTraversal SetterTrait where
traversed θ = Setter (\f -> runIdentity . θ (Identity . f))
instance FromTraversal FoldTrait where
traversed θ = Fold (\t -> getConst . θ (Const . t))
data SetterTrait s t a b = Setter ((a -> b) -> s -> t)
instance Optical SetterTrait where
type OptDens SetterTrait ζ = FromSetter ζ
cloneOptic (Setter η) = sets η
Setter s ∘ Setter σ = Setter $ s . σ
type ASetter s t a b = Optic SetterTrait s t a b
type Setter s t a b = ∀ c . FromSetter c => Optic c s t a b
class FromTraversal c => FromSetter c where
sets :: ((a -> b) -> s -> t) -> c s t a b
instance FromSetter SetterTrait where
sets = Setter
data FoldTrait s t a b = Fold (∀ r . Monoid r => (a -> r) -> s -> r)
instance Optical FoldTrait where
type OptDens FoldTrait ζ = FromFold ζ
cloneOptic (Fold η) = folds η
Fold η ∘ Fold θ = Fold (η . θ)
type AFold s t a b = Optic FoldTrait s t a b
type Fold s t a b = ∀ c . FromFold c => Optic c s t a b
class FromTraversal c => FromFold c where
folds :: (∀ r . Monoid r => (a -> r) -> s -> r) -> c s t a b
folded :: Foldable f => c (f a) t a b
folded = folds foldMap
instance FromFold FoldTrait where
folds = Fold