简体   繁体   English

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

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

In category theory, is the filter operation considered a morphism? 在范畴理论中, filter操作是否被视为态射? If yes, what kind of morphism is it? 如果是,那是什么样的态射? Example (in Scala) 示例(在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

In this answer, I will assume that you are talking about filter on Set (the situation seems messier for other datatypes). 在这个答案中,我将假设您正在讨论Set filter (其他数据类型的情况似乎更加混乱)。

Let's first fix what we are talking about. 让我们先解决我们所说的问题。 I will talk specifically about the following function (in Scala): 我将具体谈谈以下函数(在Scala中):

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

When we write it down this way, we see clearly that it's a polymorphic function with type parameter A that maps predicates A => Boolean to functions that map Set[A] to other Set[A] . 当我们以这种方式写下它时,我们清楚地看到它是一个带有类型参数A的多态函数,它将谓词A => Boolean映射到Set[A]映射到其他Set[A]函数。 To make it a "morphism", we would have to find some categories first, in which this thing could be a "morphism". 为了使它成为“态射”,我们必须首先找到一些类别,其中这个东西可能是“态射”。 One might hope that it's natural transformation, and therefore a morphism in the category of endofunctors on the "default ambient category-esque structure" usually referred to as " Hask " (or " Scal "? " Scala "?). 有人可能会希望它的自然转化,因此,在“默认环境类式的结构”中endofunctors类别态射通常被称为“ Hask ”(或“ Scal ‘?’ Scala ”?)。 To show that it's natural, we would have to check that the following diagram commutes for every f: B => A : 为了表明它是自然的,我们必须检查下面的图表是否为每个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]]

however, here we fail immediately, because it's not clear what to even put on the horizontal arrow at the bottom, since the assignment A -> Hom[Set[A], Set[A]] doesn't even seem functorial (for the same reasons why A -> End[A] is not functorial, see here and also here ). 然而,在这里我们立刻失败了,因为它不清楚甚至放在底部的水平箭头上,因为赋值A -> Hom[Set[A], Set[A]]甚至看起来都不是很有趣(对于同样的原因,为什么A -> End[A]不是函数,请参见此处此处 )。

The only "categorical" structure that I see here for a fixed type A is the following: 我在这里看到的固定类型A的唯一“分类”结构如下:

  • Predicates on A can be considered to be a partially ordered set with implication, that is p LEQ q if p implies q (ie either p(x) must be false, or q(x) must be true for all x: A ). 上谓词A可以被认为是部分有序集与含义,也就是p LEQ q如果p意味着q (即,或者p(x)必须为假,或者q(x)必须是真实的所有x: A
  • Analogously, on functions Set[A] => Set[A] , we can define a partial order with f LEQ g whenever for each set s: Set[A] it holds that f(s) is subset of g(s) . 类似地,在函数Set[A] => Set[A] ,我们可以为每个集合定义一个f LEQ g的偏序s: Set[A]它认为f(s)g(s)子集。

Then filter[A] would be monotonic, and therefore a functor between poset-categories. 然后filter[A]将是单调的,因此是poset类别之间的函子。 But that's somewhat boring. 但那有点无聊。

Of course, for each fixed A , it (or rather its eta-expansion) is also just a function from A => Boolean to Set[A] => Set[A] , so it's automatically a "morphism" in the " Hask -category". 当然,对于每个固定的A ,它(或者说它的eta扩展)也只是一个函数,从A => BooleanSet[A] => Set[A] ,所以它自动成为“ Hask ”中的“态射” -类别”。 But that's even more boring. 但那更无聊。

One interesting way of looking at this matter involves not picking filter as a primitive notion. 查看此事的一个有趣方式是不选择filter作为原始概念。 There is a Haskell type class called Filterable which is aptly described as : 有一个名为Filterable的Haskell类型,它被恰当地描述为

Like Functor , but it [includes] Maybe effects. Functor一样,但它[包括] Maybe效果。

Formally, the class Filterable represents a functor from Kleisli Maybe to Hask . 从形式上看,类Filterable代表Kleisli也许Hask函子。

The morphism mapping of the "functor from Kleisli Maybe to Hask " is captured by the mapMaybe method of the class, which is indeed a generalisation of the homonymous Data.Maybe function: Kleisli MaybeHask的仿函数”的态射映射由类的mapMaybe方法捕获,这确实是同名Data.Maybe函数的推广:

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

The class laws are simply the appropriate functor laws (note that Just and (<=<) are, respectively, identity and composition in Kleisli Maybe ): 阶级法则只是适当的子法则(请注意Just(<=<)分别是Kleisli中的身份和构成):

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

The class can also be expressed in terms of catMaybes ... 该课程也可以用catMaybes来表达......

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

... which is interdefinable with mapMaybe (cf. the analogous relationship between sequenceA and traverse )... ...与mapMaybe可以相互mapMaybe (参见sequenceAtraverse之间的类似关系)......

catMaybes = mapMaybe id
mapMaybe g = catMaybes . fmap g

... and amounts to a natural transformation between the Hask endofunctors Compose f Maybe and f . ......相当于Hask endofunctors之间的自然转换Compose f Maybef

What does all of that have to do with your question? 所有这些都与你的问题有什么关系? Firstly, a functor is a morphism between categories, and a natural transformation is a morphism between functors. 首先,仿函数是类别之间的态射,自然变换是仿函数之间的态射。 That being so, it is possible to talk of morphisms here in a sense that is less boring than the "morphisms in Hask " one . 既然如此,就可以在某种意义上谈论这里的态射, 这种态度不像哈斯克斯的态射”那样乏味 You won't necessarily want to do so, but in any case it is an existing vantage point. 你不一定这样做,但在任何情况下,现有的有利位置。

Secondly, filter is, unsurprisingly, also a method of Filterable , its default definition being: 其次, filter也是一种Filterable方法,毫不奇怪,它的默认定义是:

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

Or, to spell it using another cute combinator : 或者,使用另一个可爱的组合器拼写它:

filter p = mapMaybe (ensure p)

That indirectly gives filter a place in this particular constellation of categorical notions. 这间接地使filter在这个特定的分类概念星座中占有一席之地。

To answer are question like this, I'd like to first understand what is the essence of filtering. 回答是这样的问题,我想首先了解过滤的本质是什么。

For instance, does it matter that the input is a list? 例如,输入是一个列表是否重要? Could you filter a tree? 你能过滤一棵树吗? I don't see why not! 我不明白为什么不! You'd apply a predicate to each node of the tree and discard the ones that fail the test. 您将谓词应用于树的每个节点,并丢弃未通过测试的节点。

But what would be the shape of the result? 但结果的形状是什么? Node deletion is not always defined or it's ambiguous. 节点删除并不总是被定义,或者它是不明确的。 You could return a list. 你可以返回一个清单。 But why a list? 但为什么要列出? Any data structure that supports appending would work. 任何支持追加的数据结构都可行。 You also need an empty member of your data structure to start the appending process. 您还需要数据结构的空成员来启动附加过程。 So any unital magma would do. 所以任何单位岩浆都会这样做。 If you insist on associativity, you get a monoid. 如果你坚持相关性,你会得到一个幺半群。 Looking back at the definition of filter , the result is a list, which is indeed a monoid. 回顾filter的定义,结果是一个列表,这确实是一个幺半群。 So we are on the right track. 所以我们走在正确的轨道上。

So filter is just a special case of what's called Foldable : a data structure over which you can fold while accumulating the results in a monoid. 因此, filter只是所谓的Foldable一种特殊情况:一种数据结构,您可以在将结果累积到一个幺半群时折叠。 In particular, you could use the predicate to either output a singleton list, if it's true; 特别是,你可以使用谓词来输出单例列表,如果它是真的; or an empty list (identity element), if it's false. 或者一个空列表(标识元素),如果它是假的。

If you want a categorical answer, then a fold is an example of a catamorphism, an example of a morphism in the category of algebras. 如果你想要一个绝对的答案,那么折叠就是一个变形现象的例子,这是代数范畴中的态射的一个例子。 The (recursive) data structure you're folding over (a list, in the case of filter ) is an initial algebra for some functor (the list functor, in this case), and your predicate is used to define an algebra for this functor. 您正在折叠的(递归)数据结构(列表,在filter的情况下)是某个仿函数的初始代数(在本例中为列表仿函数),并且您的谓词用于为此仿函数定义代数。

filter can be written in terms of foldRight as: filter可以用foldRight写成:

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

foldRight on lists is a map of T-algebras (where here T is the List datatype functor), so filter is a map of T-algebras. foldRight on lists是T-algebras的映射(这里T是List数据类型foldRight函数),因此filter是T-algebras的映射。

The two algebras in question here are the initial list algebra 这里讨论的两个代数是初始列表代数

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

and, let's say the "filter" algebra, 而且,让我们说“过滤器”代数,

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

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

Let's call filter(p, _) the unique map from the initial algebra to the filter algebra in this case (it is called fold in the general case). 在这种情况下filter(p, _)让我们将filter(p, _)称为从初始代数到过滤器代数的唯一映射(在一般情况下称为fold )。 The fact that it is a map of algebras means that the following equations are satisfied: 它是代数映射的事实意味着满足以下等式:

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