Skip to content

Commit e23c508

Browse files
Isomorphisms as optics
1 parent b31fddb commit e23c508

File tree

5 files changed

+51
-7
lines changed

5 files changed

+51
-7
lines changed

src/Proarrow/Core.hs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,14 @@ module Proarrow.Core
2626
, Promonad(..)
2727
-- ** Promonad Utilities
2828
, arr
29+
-- * Isomorphisms
30+
, Optic
31+
, Iso
32+
, Iso'
33+
, AnIso
34+
, iso
35+
, from
36+
, Exchange(..)
2937
-- * Object Identities
3038
, Obj, obj, src, tgt
3139
-- * Type Family Utilities
@@ -198,3 +206,22 @@ type family UN (w :: j -> k) (wa :: k) :: j
198206

199207
-- | @Is w a@ checks that the kind @a@ is a kind wrapped by @w@.
200208
type Is w a = a ~ w (UN w a)
209+
210+
-- * Isomophisms (as optics)
211+
212+
type Optic c s t a b = forall p. c p => p a b -> p s t
213+
type Iso s t a b = Optic Profunctor s t a b
214+
type Iso' s a = Iso s s a a
215+
216+
iso :: (s ~> a) -> (b ~> t) -> Iso s t a b
217+
iso sa bt = dimap sa bt
218+
219+
data Exchange a b s t = Exchange (s ~> a) (b ~> t)
220+
instance CategoryOf k => Profunctor (Exchange a b :: k +-> k) where
221+
dimap l r (Exchange sa bt) = Exchange (sa . l) (r . bt)
222+
r \\ Exchange sa bt = r \\ sa \\ bt
223+
224+
type AnIso s t a b = Exchange a b a b -> Exchange a b s t
225+
226+
from :: (CategoryOf k, Ob (a :: k), Ob b) => AnIso s t a b -> Iso b a t s
227+
from l = case l (Exchange id id) of Exchange sa bt -> iso bt sa
Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,17 @@
11
module Proarrow.Profunctor.Constant where
22

3-
import Proarrow.Core (CategoryOf (..), Promonad (..), type (+->))
3+
import Proarrow.Core (CategoryOf (..), Promonad (..), type (+->), Optic)
44
import Proarrow.Functor (FunctorForRep (..))
5+
import Proarrow.Profunctor.Representable (rep, Rep)
6+
import Proarrow.Profunctor.Corepresentable (corep, Corep)
57

68
data family Constant :: k -> j +-> k
79
instance (CategoryOf j, CategoryOf k, Ob c) => FunctorForRep (Constant c :: j +-> k) where
810
type Constant c @ a = c
911
fmap _ = id
12+
13+
view :: forall {k} {c} (s :: k) (t :: k) a b. (CategoryOf k, Ob a, Ob b, c (Rep (Constant a))) => Optic c s t a b -> s ~> a
14+
view l = rep @(Constant a) l id
15+
16+
review :: forall {k} {c} (s :: k) (t :: k) a b. (CategoryOf k, Ob a, Ob b, c (Corep (Constant b))) => Optic c s t a b -> b ~> t
17+
review l = corep @(Constant b) l id

src/Proarrow/Profunctor/Corepresentable.hs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ module Proarrow.Profunctor.Corepresentable where
44

55
import Data.Kind (Constraint)
66

7-
import Proarrow.Core (CategoryOf (..), Profunctor (..), Promonad (..), type (+->), lmap)
7+
import Proarrow.Core (CategoryOf (..), Profunctor (..), Promonad (..), type (+->), lmap, Iso, iso)
88
import Proarrow.Object (obj, Obj)
99
import Proarrow.Functor (FunctorForRep (..))
1010

@@ -45,4 +45,7 @@ instance (FunctorForRep f) => Corepresentable (Corep f) where
4545
type Corep f %% a = f @ a
4646
coindex (Corep f) = f
4747
cotabulate = Corep
48-
corepMap = fmap @f
48+
corepMap = fmap @f
49+
50+
corep :: forall f a b a' b'. Ob a => Iso (f @ a ~> b) (f @ a' ~> b') (Corep f a b) (Corep f a' b')
51+
corep = iso Corep unCorep

src/Proarrow/Profunctor/Representable.hs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import Data.Kind (Constraint)
66
import Prelude (type (~))
77

88
import Proarrow.Category.Enriched.ThinCategory (Discrete, Thin, ThinProfunctor (..), withEq)
9-
import Proarrow.Core (CategoryOf (..), Profunctor (..), Promonad (..), (:~>), type (+->), rmap)
9+
import Proarrow.Core (CategoryOf (..), Profunctor (..), Promonad (..), (:~>), type (+->), rmap, Iso, iso)
1010
import Proarrow.Functor (FunctorForRep (..))
1111
import Proarrow.Object (Obj, obj, tgt, src)
1212
import Proarrow.Profunctor.Corepresentable (Corepresentable (..), dimapCorep, trivialCorep)
@@ -95,4 +95,7 @@ instance (FunctorForRep f) => Representable (Rep f) where
9595
type Rep f % a = f @ a
9696
index (Rep f) = f
9797
tabulate = Rep
98-
repMap = fmap @f
98+
repMap = fmap @f
99+
100+
rep :: forall f a b a' b'. Ob b => Iso (a ~> f @ b) (a' ~> f @ b') (Rep f a b) (Rep f a' b')
101+
rep = iso Rep unRep

src/Proarrow/Profunctor/Wrapped.hs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ module Proarrow.Profunctor.Wrapped where
22

33
import Proarrow.Category.Instance.Prof (Prof (..))
44
import Proarrow.Category.Monoidal (MonoidalProfunctor (..))
5-
import Proarrow.Core (Profunctor (..), Promonad (..))
5+
import Proarrow.Core (Profunctor (..), Promonad (..), Iso, iso)
66
import Proarrow.Monoid (Comonoid (..), Monoid (..))
77
import Proarrow.Profunctor.Day (Day (..), DayUnit (..))
88
import Proarrow.Category.Enriched.Dagger (DaggerProfunctor (..))
@@ -44,4 +44,7 @@ instance (Corepresentable p) => Corepresentable (Wrapped p) where
4444
type Wrapped p %% a = p %% a
4545
coindex (Wrapped p) = coindex p
4646
cotabulate f = Wrapped (cotabulate f)
47-
corepMap = corepMap @p
47+
corepMap = corepMap @p
48+
49+
wrapped :: Iso (p a b) (p a' b') (Wrapped p a b) (Wrapped p a' b')
50+
wrapped = iso Wrapped unWrapped

0 commit comments

Comments
 (0)