haskell - 为什么在 Haskell 中类型同义词不允许递归?

标签 haskell types

任何人都可以解释为什么这些都可以愉快地编译:

data A a b = A { a :: a, b :: b }
newtype B a = B (A a (B a))
newtype C = C (A Int C)

但是我不能通过类型同义词创建类似的递归定义类型?
type B a = A a (B a)
type C = A Int C

虽然很明显data B a = A { a :: a, b :: B a }工作得很好。

有什么方法可以避免在我希望类型递归的任何地方处理那个额外的构造函数 X ?我主要是传递选择 b 的访问器函数。无论如何,所以我基本上没问题,但是如果存在简单的规避机制,我想知道它。

我应该使用任何编译指示来提高专用数据类型 C 的性能?只是专门的东西?

A a b 之间复制的任何巧妙技巧和 A c d仅定义 a -> bc -> d映射而不复制记录两次?恐怕A的领域将在 future 发生变化。也许是 Haskell 模板?

最佳答案

这与 Equi-recursive types 有关与 iso-recursive types 相比. Haskell 使用 iso-recursive 类型实现递归类型,这需要程序员在类型递归发生时告诉类型检查器。您标记它的方式是使用特定的构造函数,简单的类型同义词不允许您拥有。

等递归类型允许编译器推断递归发生的位置,但它会导致更复杂的类型检查器,并且在某些看似简单的情况下,问题是无法确定的。

如果您想很好地讨论 equi 与 iso 递归类型,请查看 Benjamin Pierce 的优秀 Types and Programming Languages

简短的回答:因为类型同义词不引入构造函数,并且 haskell 需要构造函数在类型级别显式标记递归,所以不能使用递归类型同义词。

关于haskell - 为什么在 Haskell 中类型同义词不允许递归?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8963376/

相关文章:

haskell - 数据类型无效

java - 为什么我会收到此泛型类型的未经检查的转换警告?

Haskell - 搜索元组列表,返回第二个元素

haskell - 如何将自由的一元 DSL 与状态交错,但在程序中解释状态?

c++ - auto 用于容器的类型是什么?

c++ - 检查对象类型真的总是糟糕设计的标志吗?

java - 在java中创建oracle类型

haskell - 编写丰富的 Haskell "show"函数的正确方法是什么?

Haskell Lambda 帮助 - 从 lambda 术语输入中拆分术语

haskell - 从 runDb 捕获异常