`arr fst` 是如何自然转换的?

How is `arr fst` a natural transformation?

我刚才问过this question。这是关于以下箭头法则:

arr fst . first f = f . arr fst -- (.) :: Category k => k b c -> k a b -> k a c

在post下的评论Asad Saeeduddin explained it in terms of natural transformations. I would like to check whether I got their explanation right and compare it a bit to Bartosz Milewski's article on natural transformations.

所以,自然变换的定义是:

我们有两个类别 CD 以及仿函数 F, G : C ~> D。自然变换 αD 中的一系列箭头,使得:

  1. 这些箭头从 F 的结果指向 G 的结果。也就是说,对于 C 中的每个对象 a,都存在一个箭头(在 a 处称为 α 组件)α_a :: F a ~> G a.
  2. 对于每个 f :: a ~> bab 作为 C 中的对象,拥有:Gf . α_a = α_b . Ff。这就是自然。

基本上,我们需要弄清楚在我们的例子中有四个变量:CDFG

据我所知:

  • CD是同一类任意类型,k a b是其中的箭头,其中kArrow 我们正在使用的实例。因此,FG 是内函子。

  • F(, c)GIdentity。换句话说,如果我们不再使用类型,我们将 F 映射到 first,将 G 映射到 idNOT 考虑类型可能会更容易,因为 CategoryArrow 类 帮助我们构建类别的箭头,而不是对象

这样对吗?

此外,Bartosz Milewski wrote those ideas down这样的:

fmap f . alpha = alpha . fmap f

据我所知,我们需要一个更通用的形式来满足我们的目的,因为这里 alpha :: forall a. F a -> G a 仅将 Hask 作为其工作的类别进行处理。还是我错了? fmap在这张照片中有什么地方?

您无需担心额外的类别,因为 arr fst 不涉及任意 Arrow,只是它的 (,) 个实例。

在Haskell中,f a -> g a类型的函数对于某些函子fc是自然变换。在 arr fst :: (b -> c) -> (b, c) 的情况下,让 f ~ (->) bg ~ (,) b.

As far as I get it:

  • C and D are the same category of arbitrary types, k a b being arrows in it, where k is the Arrow instance we are working with. Therefore, F and G are endofunctors.

  • F is (, c) and G is Identity. In other words, if we no longer work with types, we map F with first and G with id. [...]

是的,就是这样。 arr fst :: k (b, c) bkc 的每个选择都为我们提供了 (, c) 内函子和 k 范畴中的恒等函子之间的自然转换。进行特化后,我们得到了一个看起来更像自然变换的签名:

arr @K (fst @_ @C) :: forall b. K (b, C) b

Moreover, Bartosz Milewski wrote those ideas down like that:

fmap f . alpha = alpha . fmap f

As far as I get it, we need a more general form for our purposes as here alpha :: forall a. F a -> G a deals with Hask only as the category it works with. Or am I wrong? Which place does fmap have in this picture?

也正确。 fmap 必须用所涉及函子的适当态射映射替换。在你的例子中,这些恰好是 firstid,正如你之前注意到的那样,这让我们回到了我们开始的箭头法则。

(至于替换fmapFunctor的方法从特定的函子态射映射中抽象出来,用一个更一般的类比,这需要做出适当的安排,以便我们可以表达涉及的函子Haskell 代码中的非 Hask 类别。您可能想看看 constrained-categories and data-category 如何处理它。)