{-# LANGUAGE RankNTypes #-} module Optics ( Optic , Adapter , Lens , Prism , Traversal , Monoidal(..) ) where import Data.Profunctor import Data.Distributive class Profunctor p => Monoidal p where par :: p a b -> p c d -> p (a, c) (b, d) empty :: p () () cross :: (a -> c) -> (b -> d) -> (a, b) -> (c, d) cross :: forall a c b d. (a -> c) -> (b -> d) -> (a, b) -> (c, d) cross a -> c f b -> d g (a x, b y) = (a -> c f a x, b -> d g b y) instance Monoidal (->) where par :: forall a c b d. (a -> c) -> (b -> d) -> (a, b) -> (c, d) par = forall a c b d. (a -> c) -> (b -> d) -> (a, b) -> (c, d) cross empty :: () -> () empty = forall a. a -> a id type Optic p a b s t = p a b -> p s t type Adapter a b s t = forall p. (Profunctor p) => Optic p a b s t type Lens a b s t = forall p. (Strong p) => Optic p a b s t type Prism a b s t = forall p. (Costrong p) => Optic p a b s t type Traversal a b s t = forall p. ( Strong p , Costrong p , Monoidal p ) => Optic p a b s t