什么是亵渎者和箭头之间的关系?

时间:2016-07-03 11:24:15

标签: haskell functor arrows category-theory

显然,每个Arrow都是Strong发送者。确实^>>>>^对应lmaprmapfirst'second'firstsecond相同。同样,每个ArrowChoice也是Choice

与箭相比,影响者缺乏的是构成它们的能力。如果我们添加构图,我们会得到一个箭头吗?换句话说,如果(强)profunctor也是category,它是否已经是箭头?如果不是,缺少什么?

2 个答案:

答案 0 :(得分:30)

  

与箭相比,影响者缺乏的是构成它们的能力。如果我们添加构图,我们会得到一个箭头吗?

幺半群

这正是“Notions of Computation as Monoids”第6节中解决的问题,它解析了(相当密集的)“Categorical semantics for arrows”的结果。 “概念”是一篇很好的论文,因为虽然它深入研究范畴理论,但它(1)并不认为读者不仅仅是粗略的抽象代数知识,(2)用Haskell代码说明大多数偏头痛诱导数学。我们可以在这里简要总结一下论文的第6部分:

说我们有

class Profunctor p where
  dimap :: (contra' -> contra) -> (co -> co') -> p contra co -> p contra' co'

你在Haskell中对标准符号进行了标准的,负面和正面的dividin'编码。现在这个数据类型,

data (⊗) f g contra co = forall x. (f contra x) ⊗ (g x co)
Data.Profunctor.Composition中实现的

就像profunctor的组合一样。例如,我们可以展示一个合法的实例Profunctor

instance (Profunctor f, Profunctor g) => Profunctor (f ⊗ g) where
  dimap contra co (f ⊗ g) = (dimap contra id f) ⊗ (dimap id co g)

由于时间和空间的原因,我们将手动证明它是合法的。

行。现在有趣的部分。假设我们这个类型类:

class Profunctor p => ProfunctorMonoid p where
  e :: (a -> b) -> p a b
  m :: (p ⊗ p) a b -> p a b

这更像是挥手致意,是一种在Haskell中编码profunctor monoids概念的方法。具体来说,这是幺半群类Pro中的幺半群,它是函数类[C^op x C, Set]的幺半群结构,其中为张量,Hom为其单位。所以这里有很多非特异性的数学用法,但是你应该阅读这篇论文。

然后我们看到ProfunctorMonoidArrow几乎是同构的......差不多。

instance ProfunctorMonoid p => Category p where
  id = dimap id id
  (.) pbc pab = m (pab ⊗ pbc)

instance ProfunctorMonoid p => Arrow p where
  arr = e
  first = undefined

instance Arrow p => Profunctor p where
  lmap = (^>>)
  rmap = (>>^)

instance Arrow p => ProfunctorMonoid p where
  e = arr
  m (pax ⊗ pxb) = pax >> pxb

当然,我们忽略了这里的类型类法则,但正如文章所示,它们确实很有效。

现在我说几乎是因为我们无法实现first。我们真正做的是证明了ProfunctorMonoid前箭头之间的同构。本文调用了Arrow而没有first 前箭头。然后它继续显示

class Profunctor p => StrongProfunctor p where
  first :: p x y -> p (x, z) (y, z)

class StrongProfunctor p => StrongProfunctorMonoid p where
  e :: (a -> b) -> p a b
  m :: (p ⊗ p) a b -> p a b

Arrow所需的同构是必要且充分的。 “强”这个词来自于类别理论中的一个特定概念,并且在论文中以更好的写作和更丰富的细节来描述。

总结一下:

  • “精灵”类别中的幺半群是前箭头,反之亦然。 (该论文的前一版本使用术语“弱箭头”而不是前箭头,我猜也是如此。)

  • 强健身分类中的幺半群是箭头,反之亦然。

  • 由于monad是endofunctor类别中的monoid,我们可以想到SAT类比Functor : Profunctor :: Monad : Arrow。这是计算概念作为幺半群纸的真正重点。

  • 幺半群和幺半群是温和的海洋生物,无处不在,有些学生在没有被教授幺半群的情况下会通过计算机科学或软件工程教育,这是一种耻辱。

  • 分类理论很有趣。

  • Haskell很有趣。

答案 1 :(得分:6)

@ haoformayor的回答(以及参考文献)是对基础范畴理论的深刻见解 - 幺半群类别相当漂亮! - 但是我想一些代码向您展示如何将Arrow变成Strong Category,反之亦然,因为它们出现在各自的图书馆中可能会作为一个有用的附录。

import Control.Arrow
import Control.Category
import Data.Profunctor
import Data.Profunctor.Strong
import Prelude hiding (id, (.))

单程......

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

......和其他......

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