[英]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 => Boolean
到Set[A] => Set[A]
,所以它自動成為“ Hask
”中的“態射” -類別”。 但那更無聊。
查看此事的一個有趣方式是不選擇filter
作為原始概念。 有一個名為Filterable
的Haskell類型,它被恰當地描述為 :
像
Functor
一樣,但它[包括]Maybe
效果。從形式上看,類
Filterable
代表Kleisli也許到Hask函子。
“ Kleisli Maybe
到Hask的仿函數”的態射映射由類的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
(參見sequenceA
和traverse
之間的類似關系)......
catMaybes = mapMaybe id
mapMaybe g = catMaybes . fmap g
......相當於Hask endofunctors之間的自然轉換Compose f Maybe
和f
。
所有這些都與你的問題有什么關系? 首先,仿函數是類別之間的態射,自然變換是仿函數之間的態射。 既然如此,就可以在某種意義上談論這里的態射, 這種態度不像 “ 哈斯克斯的態射”那樣乏味 。 你不一定想這樣做,但在任何情況下,現有的有利位置。
其次, 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.