Haskell 什么';ProFunctor和arrows之间的关系是什么?
显然,每个Haskell 什么';ProFunctor和arrows之间的关系是什么?,haskell,functor,category-theory,arrows,profunctor,Haskell,Functor,Category Theory,Arrows,Profunctor,显然,每个箭头都是一个profunctor。实际上,和>^对应于lmap和rmap。和first'和second'与first和second完全相同。同样,每个箭头选项也都是 与箭头相比,ProFunctor缺少的是合成箭头的能力。如果我们加上构图,我们会得到箭头吗?换句话说,如果一个(强)profinctor也是一个,那么它已经是一个箭头了吗?如果没有,还缺少什么 与箭头相比,ProFunctor缺少的是合成箭头的能力。如果我们加上构图,我们会得到箭头吗 幺半群 这正是“从(相当密集的)”中解
箭头都是一个profunctor。实际上,和>^
对应于lmap
和rmap
。和first'
和second'
与first
和second
完全相同。同样,每个箭头选项也都是
与箭头相比,ProFunctor缺少的是合成箭头的能力。如果我们加上构图,我们会得到箭头吗?换句话说,如果一个(强)profinctor也是一个,那么它已经是一个箭头了吗?如果没有,还缺少什么
与箭头相比,ProFunctor缺少的是合成箭头的能力。如果我们加上构图,我们会得到箭头吗
幺半群
这正是“从(相当密集的)”中解包结果”第6节中所述的问题。《概念》是一篇伟大的论文,因为它深入到范畴理论中,它(1)并不认为读者对抽象代数有更多的粗略知识,(2)用Haskell代码说明了大多数诱发偏头痛的数学。我们可以在此简要总结本文第6节:
说我们有
class Profunctor p where
dimap :: (contra' -> contra) -> (co -> co') -> p contra co -> p contra' co'
您的bog标准,Haskell中profunctor的正负dividin'编码。现在这个数据类型
data (⊗) f g contra co = forall x. (f contra x) ⊗ (g x co)
如中所实现的,其行为类似于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幺半群概念的方法,而且挥手的次数要多得多。具体来说,这是单倍体类别Pro
中的一个单倍体,它是带有⊗
作为张量,Hom
作为其单位。所以这里有很多非常特殊的数学术语需要解释,但是你应该读一下这篇文章
然后我们看到,profunctoromoid
与Arrow
同构。。。差不多
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
当然,我们在这里忽略了类型类法则,但是,正如论文所显示的,它们的效果确实非常好
现在我这么说几乎是因为我们无法首先实现。我们真正做的是证明了ProfunctorMonoid
和pre-arrows之间的同构。本文称Arrow
为pre-Arrow,而不使用第一个。然后它继续证明了这一点
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
对于箭头所需的同构是必要且充分的。“强”这个词来自范畴理论中的一个特定概念,这篇论文以比我所能想到的更好的文字和更丰富的细节对它进行了描述
因此,总结一下:
- ProFunctor类中的幺半群是预箭头,反之亦然。(以前版本的论文使用了“弱箭头”一词,而不是预箭头,我想这也没关系。)
- 强函数范畴中的幺半群是箭头,反之亦然
- 由于monad是内函子范畴中的幺半群,我们可以考虑SAT类比
函子:profuncor::monad:Arrow
。这是作为幺半群的计算概念的真正要旨
- 幺半群和幺半群类是随处可见的温和的海洋生物,令人遗憾的是,一些学生将在没有学习幺半群的情况下接受计算机科学或软件工程教育
- 范畴理论很有趣
- 哈斯克尔很有趣
@haoformayor的答案(以及参考文献)是对基本范畴理论的一个伟大洞察——单倍体范畴相当漂亮但我认为,一些代码向您展示了如何将箭头
转化为强类别
,反之亦然,因为它们出现在各自的库中,这可能是一个有用的补充
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
阿罗正是强项?链接到:。用那个dimap f id
片段,你让我大开眼界。最后,我意识到Strong
和Category
对于箭头
!:)来说已经足够了谢谢dimap id f id
,是的。