What's the relationship between profunctors and arrows?

后端 未结 2 853
心在旅途
心在旅途 2020-12-24 13:09

Apparently, every Arrow is a Strong profunctor. Indeed ^>> and >>^ correspond to lmap and rmap. And fir

2条回答
  •  天涯浪人
    2020-12-24 13:26

    @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
    

提交回复
热议问题