Apparently, every Arrow
is a Strong profunctor. Indeed ^>> and >>^
correspond to lmap
and rmap
. And fir
@haoformayor's answer (and the referenced paper) is a great insight into the underlying category theory - monoidal categories are rather beautiful! - but I thought some code showing you how to turn an Arrow
into a Strong Category
and vice versa as they appear in their respective libraries might make a helpful addendum.
import Control.Arrow
import Control.Category
import Data.Profunctor
import Data.Profunctor.Strong
import Prelude hiding (id, (.))
One way...
newtype WrapP p a b = WrapP { unwrapP :: p a b }
instance Category p => Category (WrapP p) where
id = WrapP id
WrapP p . WrapP q = WrapP (p . q)
instance (Category p, Strong p) => Arrow (WrapP p) where
first = WrapP . first' . unwrapP
second = WrapP . second' . unwrapP
-- NB. the first usage of id comes from (->)'s Category instance (id :: a -> a)
-- but the second uses p's instance (id :: p a a)
arr f = WrapP $ dimap f id id
... and t'other...
newtype WrapA p a b = WrapA { unwrapA :: p a b }
instance Arrow p => Profunctor (WrapA p) where
dimap f g p = WrapA $ arr f >>> unwrapA p >>> arr g
instance Arrow p => Strong (WrapA p) where
first' = WrapA . first . unwrapA
second' = WrapA . second . unwrapA