利用一些理论,可以恢复递归类型的折叠/展开类型,包括列表,了解它们为什么是它们。
设为A固定类型。类型“ As 的列表”满足同构
List ~~ Either () (A, List)
可以读作“列表值是一个特殊值(空列表),或者是一个类型的值,A后跟一个列表值”。
用更简洁的表示法,我们可以写成Either中缀+:
List ~~ () + (A, List)
现在,如果我们让F b = () + (A, b),我们有
List ~~ F List
上面是一个不动点方程,在使用递归类型时总是会出现。对于由我们定义的任何递归类型,T ~~ F T我们可以推导出相关折叠/展开的类型(也称为cata/ana或归纳/共归纳原则)
fold :: (F b -> b) -> T -> b
unfold :: (b -> F b) -> b -> T
在列表的情况下,我们得到
fold :: ((() + (A, b)) -> b) -> List -> b
unfoldr :: (b -> (() + (A, b))) -> b -> List
展开也可以重写,注意Maybe c ~~ () + c:
unfoldr :: (b -> Maybe (A, b)) -> b -> List
折叠可以改写为
((x + y) -> z) ~~ (x -> z, y -> z)
得到
foldr :: (() -> b, (A, b) -> b) -> List -> b
那么,因为() -> b ~~ b,
foldr :: (b, (A, b) -> b) -> List -> b
最后,由于(x, y) -> z ~~ x -> y -> z(currying),我们有
foldr :: b -> ((A, b) -> b) -> List -> b
然后再次:
foldr :: b -> (A -> b -> b) -> List -> b
最后翻转x -> y -> z ~~ y -> x -> z:
foldr :: (A -> b -> b) -> b -> List -> b
这些类型如何遵循(共)归纳原则?
域理论指出,最小固定点 ( F(T)=T) 与最小前缀点 ( ) 重合F(T)<=T,当F在某个偏序上是单调的。
归纳原理简单地指出,如果T是最小前缀点,并且F(U)<=U,那么T<=U。(证明。它是最少的!。QED。)在公式中,
(F(U) <= U) ==> (T <= U)
为了处理类型上的固定点,我们需要从 poset 切换到类别,这使得一切都变得更加复杂。非常非常粗略地,every<=被一些态射取代。例如,F(U)<=Unow 表示存在某种态射F U -> U。“单调F”意味着它F是一个函子(因为现在a<=b暗示F(a)<=F(b)变成了(a->b)暗示F a -> F b)。前缀点是 F 代数 ( F u -> u)。“最小”变成“初始”。等等。
因此折叠的类型:(暗示也是->如此)
fold :: (F u -> u) -> (T -> u)
Unfold 源自共归纳原理,该原理处理最大的后缀点T(成为余代数)
(U <= F(U)) ==> (U <= T)