繁体   English   中英

什么样的态射是类别理论中的“过滤器”?

[英]What kind of morphism is `filter` in category theory?

在范畴理论中, filter操作是否被视为态射? 如果是,那是什么样的态射? 示例(在Scala中)

val myNums: Seq[Int] = Seq(-1, 3, -4, 2)

myNums.filter(_ > 0)
// Seq[Int] = List(3, 2) // result = subset, same type

myNums.filter(_ > -99)
// Seq[Int] = List(-1, 3, -4, 2) // result = identical than original

myNums.filter(_ > 99)
// Seq[Int] = List() // result = empty, same type

在这个答案中,我将假设您正在讨论Set filter (其他数据类型的情况似乎更加混乱)。

让我们先解决我们所说的问题。 我将具体谈谈以下函数(在Scala中):

def filter[A](p: A => Boolean): Set[A] => Set[A] = 
                                     s => s filter p

当我们以这种方式写下它时,我们清楚地看到它是一个带有类型参数A的多态函数,它将谓词A => Boolean映射到Set[A]映射到其他Set[A]函数。 为了使它成为“态射”,我们必须首先找到一些类别,其中这个东西可能是“态射”。 有人可能会希望它的自然转化,因此,在“默认环境类式的结构”中endofunctors类别态射通常被称为“ Hask ”(或“ Scal ‘?’ Scala ”?)。 为了表明它是自然的,我们必须检查下面的图表是否为每个f: B => A通勤f: B => A

                       - o f
Hom[A, Boolean] ---------------------> Hom[B, Boolean]
     |                                       |
     |                                       |
     |                                       |
     | filter[A]                             | filter[B]
     |                                       |
     V                  ???                  V
Hom[Set[A], Set[A]] ---------------> Hom[Set[B], Set[B]]

然而,在这里我们立刻失败了,因为它不清楚甚至放在底部的水平箭头上,因为赋值A -> Hom[Set[A], Set[A]]甚至看起来都不是很有趣(对于同样的原因,为什么A -> End[A]不是函数,请参见此处此处 )。

我在这里看到的固定类型A的唯一“分类”结构如下:

  • 上谓词A可以被认为是部分有序集与含义,也就是p LEQ q如果p意味着q (即,或者p(x)必须为假,或者q(x)必须是真实的所有x: A
  • 类似地,在函数Set[A] => Set[A] ,我们可以为每个集合定义一个f LEQ g的偏序s: Set[A]它认为f(s)g(s)子集。

然后filter[A]将是单调的,因此是poset类别之间的函子。 但那有点无聊。

当然,对于每个固定的A ,它(或者说它的eta扩展)也只是一个函数,从A => BooleanSet[A] => Set[A] ,所以它自动成为“ Hask ”中的“态射” -类别”。 但那更无聊。

查看此事的一个有趣方式是不选择filter作为原始概念。 有一个名为Filterable的Haskell类型,它被恰当地描述为

Functor一样,但它[包括] Maybe效果。

从形式上看,类Filterable代表Kleisli也许Hask函子。

Kleisli MaybeHask的仿函数”的态射映射由类的mapMaybe方法捕获,这确实是同名Data.Maybe函数的推广:

mapMaybe :: Filterable f => (a -> Maybe b) -> f a -> f b

阶级法则只是适当的子法则(请注意Just(<=<)分别是Kleisli中的身份和构成):

mapMaybe Just = id
mapMaybe (g <=< f) = mapMaybe g . mapMaybe f

该课程也可以用catMaybes来表达......

catMaybes :: Filterable f => f (Maybe a) -> f a

...与mapMaybe可以相互mapMaybe (参见sequenceAtraverse之间的类似关系)......

catMaybes = mapMaybe id
mapMaybe g = catMaybes . fmap g

......相当于Hask endofunctors之间的自然转换Compose f Maybef

所有这些都与你的问题有什么关系? 首先,仿函数是类别之间的态射,自然变换是仿函数之间的态射。 既然如此,就可以在某种意义上谈论这里的态射, 这种态度不像哈斯克斯的态射”那样乏味 你不一定这样做,但在任何情况下,现有的有利位置。

其次, filter也是一种Filterable方法,毫不奇怪,它的默认定义是:

filter :: Filterable f => (a -> Bool) -> f a -> f a
filter p = mapMaybe $ \a -> if p a then Just a else Nothing

或者,使用另一个可爱的组合器拼写它:

filter p = mapMaybe (ensure p)

这间接地使filter在这个特定的分类概念星座中占有一席之地。

回答是这样的问题,我想首先了解过滤的本质是什么。

例如,输入是一个列表是否重要? 你能过滤一棵树吗? 我不明白为什么不! 您将谓词应用于树的每个节点,并丢弃未通过测试的节点。

但结果的形状是什么? 节点删除并不总是被定义,或者它是不明确的。 你可以返回一个清单。 但为什么要列出? 任何支持追加的数据结构都可行。 您还需要数据结构的空成员来启动附加过程。 所以任何单位岩浆都会这样做。 如果你坚持相关性,你会得到一个幺半群。 回顾filter的定义,结果是一个列表,这确实是一个幺半群。 所以我们走在正确的轨道上。

因此, filter只是所谓的Foldable一种特殊情况:一种数据结构,您可以在将结果累积到一个幺半群时折叠。 特别是,你可以使用谓词来输出单例列表,如果它是真的; 或者一个空列表(标识元素),如果它是假的。

如果你想要一个绝对的答案,那么折叠就是一个变形现象的例子,这是代数范畴中的态射的一个例子。 您正在折叠的(递归)数据结构(列表,在filter的情况下)是某个仿函数的初始代数(在本例中为列表仿函数),并且您的谓词用于为此仿函数定义代数。

filter可以用foldRight写成:

filter p ys = foldRight(nil)( (x, xs) => if (p(x)) x::xs else xs ) ys

foldRight on lists是T-algebras的映射(这里T是List数据类型foldRight函数),因此filter是T-algebras的映射。

这里讨论的两个代数是初始列表代数

[nil, cons]: 1 + A x List(A) ----> List(A)

而且,让我们说“过滤器”代数,

[nil, f]: 1 + A x List(A) ----> List(A)

其中f(x, xs) = if p(x) x::xs else xs

在这种情况下filter(p, _)让我们将filter(p, _)称为从初始代数到过滤器代数的唯一映射(在一般情况下称为fold )。 它是代数映射的事实意味着满足以下等式:

filter(p, nil) = nil
filter(p, x::xs) = f(x, filter(p, xs))

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM