I was looking at the classes of strong and closed profunctors:
class Profunctor p where
dimap :: (a' -> a) -> (b -> b') -> p a b -> p a' b'
class Profunctor p => Strong p where
strong :: p a b -> p (c, a) (c, b)
class Profunctor p => Closed p where
closed :: p a b -> p (c -> a) (c -> b)
((,)
is a symmetric bifunctor, so it's equivalent to the definition in "profunctors" package.)
I note both (->) a
and (,) a
are endofunctors. It seems Strong
and Closed
have a similar form:
class (Functor f, Profunctor p) => C f p where
c :: p a b -> p (f a) (f b)
Indeed, if we look at the laws, some also have a similar form:
strong . strong ≡ dimap unassoc assoc . strong
closed . closed ≡ dimap uncurry curry . closed
lmap (first f) . strong ≡ rmap (first f) . strong
lmap (. f) . closed ≡ rmap (. f) . closed
Are these both special cases of some general case?
You could add
Choice
to the list. BothStrong
andChoice
(or cartesian and cocartesian, as Jeremy Gibbons calls them) are examples of Tambara modules. I talk about the general pattern that includesClosed
in my blog post on profunctor optics (skip to the Discussion section), under the nameRelated
.