簡體   English   中英

余數據類型真的是終端代數嗎?

[英]Are codatatypes really terminal algebras?

(免責聲明:我不是 100% 確定 codatatype 是如何工作的,尤其是在不涉及終端代數時)。

考慮“類型的類別”,類似於Hask ,但可以進行任何適合討論的調整。 在這樣一個類別中,據說(1)初始代數定義數據類型,(2)終端代數定義余數據類型。

我正在努力說服自己相信(2)。

考慮函子T(t) = 1 + a * t 我同意最初的T代數是明確定義的,並且確實定義了[a] ,即a的列表。 根據定義,初始T代數是類型X和 function f:: 1+a*X -> X ,因此對於任何其他類型Y和 function g:: 1+a*Y -> Y ,有正好是一個 function m:: X -> Y使得m. f = g. T(m) m. f = g. T(m) m. f = g. T(m) (其中.表示在 Haskell 中的 function 組合運算符)。 With f interpreted as the list constructor(s), g the initial value and the step function, and T(m) the recursion operation, the equation essentially asserts the unique existance of the function m given any initial value and any step function defined in g ,這需要一個行為良好的基礎fold以及基礎類型,即a的列表。

例如, g:: Unit + (a, Nat) -> Nat可以是() -> 0 | (_,n) -> n+1 () -> 0 | (_,n) -> n+1 ,在這種情況下m定義長度 function,或者g可以是() -> 0 | (_,n) -> 0 () -> 0 | (_,n) -> 0 ,然后m定義一個常數零 function。 這里的一個重要事實是,對於任何gm始終可以唯一定義,就像fold不會對其 arguments 施加任何約束,並且始終會產生唯一的明確定義的結果。

這似乎不適用於終端代數。

考慮上面定義的相同的仿函數T 終端T代數的定義與初始代數相同,不同之處在於m現在是X -> Y類型,方程現在變為m. g = f. T(m) m. g = f. T(m) m. g = f. T(m) 據說這應該定義一個潛在的無限列表。

我同意這有時是真的。 例如,當g:: Unit + (Unit, Int) -> Int定義為() -> 0 | (_,n) -> n+1 () -> 0 | (_,n) -> n+1像以前一樣,然后m的行為使得m(0) = ()m(n+1) = Cons () m(n) 對於非負nm(n)應該是一個有限的單元列表。 對於任何負數nm(n)應該是無限長的。 可以驗證上面的等式對於這樣的gm成立。

但是,對於以下兩個修改后的g定義中的任何一個,我再也看不到任何定義明確的m了。

首先,當g再次為() -> 0 | (_,n) -> n+1 () -> 0 | (_,n) -> n+1但屬於g:: Unit + (Bool, Int) -> Int類型, m必須滿足m(g((b,i))) = Cons bm(g(i)) ,這意味着結果取決於b 但這是不可能的,因為m(g((b,i)))實際上只是m(i+1)沒有提到b ,所以方程沒有明確定義。

其次,當g再次是g:: Unit + (Unit, Int) -> Int類型但被定義為常數零 function g _ = 0時, m必須滿足m(g(())) = Nilm(g(((),i))) = Cons () m(g(i)) ,這是矛盾的,因為它們的左側是相同的,都是m(0) ,而右側永遠不是相同的。

總之,有T -代數沒有態射到假設的終端T -代數中,這意味着終端T -代數不存在。 如果有的話,codatatype Stream(或無限列表)的理論建模不能基於函子T(t) = 1 + a * t的不存在終端代數。

非常感謝上面故事中任何缺陷的暗示。

(2) 終結代數定義了余數據類型。

這是不對的, codatatypes 是終端colgebras 對於您的T函子,余代數是xf:: x -> T x的類型。 (x1, f1)(x2, f2)之間的T -coalgebra 態射是g:: x1 -> x2使得fmap g. f1 = f2. g fmap g. f1 = f2. g fmap g. f1 = f2. g 使用這個定義,終端T -代數定義了可能的無限列表(所謂的“colists”),並且終端性由unfold function 見證:

unfold :: (x -> Unit + (a, x)) -> x -> Colist a

請注意,盡管確實存在終端T代數:它只是Unit類型以及常數 function T Unit -> Unit (這可以作為任何T的終端代數)。 但這對於編寫程序並不是很有趣。

據說(1)初始代數定義數據類型,(2)終端代數定義余數據類型。

關於第二點,實際上據說終端余代數定義了余數據類型。

數據類型t由其構造函數和折疊定義。

  • 構造函數可以通過代數F t -> t來建模(例如,Peano 構造函數O: nat S: Nat -> Nat被收集為單個 function in: Unit + Nat -> Nat )。
  • 然后折疊給出變質fold f: t -> x對於任何代數f: F x -> x (對於 nats, fold: ((Unit + x) -> x) -> Nat -> x )。

codatatype t由它的析構函數和展開定義。

  • Destructors can be modelled by a coalgebra t -> F t (for example, streams have two destructors head: Stream a -> a and tail: Stream a -> Stream a , and they are collected as a single function out: Stream a -> a * Stream a )。
  • 然后展開給出變形unfold f: x -> t對於任何余代數f: x -> F x (對於流, unfold: (x -> a * x) -> x -> Stream a )。

(免責聲明:我不是 100% 確定 codatatype 是如何工作的,尤其是在不涉及終端代數時)。

余數據類型或協導數據類型只是由它的消除而不是它的引入來定義的。

似乎有時使用終端代數(非常令人困惑)來指代最終的 colgebra ,這實際上定義了余數據類型。

考慮上面定義的相同的仿函數 T。 終端 T 代數的定義與初始代數相同,不同之處在於 m 現在是 X -> Y 類型,方程現在變為 m。 g = f。 Tm值)。 據說這應該定義一個潛在的無限列表。

所以我認為這是你出錯的地方:“ mg = fT ( m )”應該顛倒過來,改為“ T ( m ) ∘ f = gm ”。 That is, the final coalgebra is defined by a carrier set S and a map g : ST ( S ) such that for any other coalgebra ( R , f : RT ( R )) there is a unique map m : RS使得T ( m ) ∘ f = gm

m由 map 遞歸地唯一定義,當f映射到Left () ) 時返回Left () ,當f映射到 Right (x, xs) 時返回Right (x, m xs) Right (x, xs) ,即它是將余代數分配給其唯一態射到最終的余代數,並表示這種類型的獨特變形/展開,這應該很容易說服自己實際上是一個可能為空且可能無限的 stream。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM