在recursion-schemes
包中,我们可以表达一个(严格为正)代数数据类型的事实
f
f
- 代数,f
- coalgebra 例如,我们可以使用以下代码
为[a]
执行此操作
-- (1) define and declare the signature functor, here called Base
data instance Prim [a] x = Nil | Cons a x deriving Functor
type instance Base [a] = Prim [a]
-- (2) demonstrate the initial algebra
instance Foldable [a] where
project [] = Nil
project (a:as) = Cons a as
-- (3) demonstrate the final coalgebra
instance Unfoldable [a] where
embed Nil = []
embed (Cons a as) = a:as
值得注意的是,对于我们有(1),(2)和(3)的任何类型,我们应该让(project, embed)
见证同构。
我的理解是,大型(或至少是严格肯定的)数据类型总是某些签名函子的最终/初始co /代数 - 事实上,它们总是两者。
所以我的问题是:为什么将Foldable
和Unfoldable
作为单独的类?数据类型何时只是一个或哪个?
目前我可以想象这对于只想提供折叠或展开界面的抽象数据类型可能有价值,但是还有其他时间吗?
答案 0 :(得分:5)
这可能不是你问题的答案,但严格来说正Haskell数据类型是初始代数并不是真的。这样做的原因是即使在Haskell的整个子集中(这是我们在推理时想要的工作!),你也有无限的数据。
例如,无限列表的折叠是部分的。