显然,Haskell中有一个叫做无限类型的东西。
例如,当我在GHCi上尝试iterate concat
时,我明白了:
*Main> iterate concat
<interactive>:24:9: error:
• Occurs check: cannot construct the infinite type: a ~ [a]
Expected type: [a] -> [a]
Actual type: [[a]] -> [a]
• In the first argument of ‘iterate’, namely ‘concat’
In the expression: iterate concat
In an equation for ‘it’: it = iterate concat
• Relevant bindings include
it :: [a] -> [[a]] (bound at <interactive>:24:1)
我的问题是,究竟什么是无限类型?它们如何适应类型理论以及我可以从哪些资源中了解它们?有没有允许无限类型的编程语言?
答案 0 :(得分:5)
显然,在Haskell中有一种称为无限类型的东西。
由于Haskell类型检查器每次出现无限类型时都会引发类型错误,我会说Haskell中有 no 无限类型。
无论如何,“无限”类型指的是类型本身中出现的类型构造函数的数量。例如[[Int]] -> Bool
提及[], Bool, Int, (->)
,因此它是有限的。如果我们可以用无限多的嵌套来编写type L = [[[[...]]]]
,我们就会有一个无限类型:一个类型,其值是列表列表的列表......永远。
无限类型可能在类型推断期间通过统一而出现。如果我写
let x = [x] in ...
然后如果T
是x
的类型,则根据定义它也必须是[x]
的类型。但是,后者显然具有[T]
类型。因此,我们必须求解方程T = [T]
,其解决方案将导致上面讨论的无限类型L
。
Haskell与几乎所有编程语言一样,拒绝无限类型,因为它们通常是程序员错误的症状。此外,我想添加无限(常规)类型可以使类型检查更加困难。我不记得有关无限类型的任何理论结果,但如果类型检查变得不可判,我也不会感到惊讶。
答案 1 :(得分:2)
&#34;无限&#34;类型并不是类型理论的一部分。一般来说,数学远离处理那些永远持续下去的事情。在形式上,您正在寻找递归类型的概念。大多数编程语言做都支持递归类型,但只有在被其他构造函数保护时才能使用。例如,在Haskell中,允许以下内容(实际上,在运行时,它将等同于其表示中的无限嵌套列表):
newtype InfinitelyNestedList a = Nest [InfinitelyNestedList a]
然而,是这种事物的形式化,这正是你所说的:equirecursive "mu" types(这应该给你一个很好的谷歌搜索起点)。混合列表类型构造函数,您可以将无限嵌套列表类型视为
µ x. [x]
我所知道的大型流行语言并没有使用equirecursive类型并且有充分的理由 - 这意味着你不再拥有主体类型。在Haskell中,每个类型都可以规范化,因此如果要检查两个类型是否相等(在编译器中),请将它们标准化并进行比较。然而,在这里,你输了。例如,以下类型都完全相同!
µ x. [x]
[[µ x. [x]]]
[[[[[[[µ x. [x]]]]]]]]
在这种情况下,编译器可以另外标准化为最简单的&#34;第一种情况 - 但总的来说,没有概念&#34;最简单的&#34;。
答案 2 :(得分:1)
&#34;无限类型&#34;就我所知,它并不是一件特别的事。我读了这行错误信息:
Occurs check: cannot construct the infinite type: a ~ [a]
仅使用&#34;无限&#34;作为描述类型的形容词,不使用&#34;无限类型&#34;作为特殊类型的名称。编译器意识到它需要一个满足a ~ [a]
的类型来为你的代码提供一个类型,并且它不能处理这样的类型。
如果只是错误消息将是完全正确的:
Occurs check: cannot construct the type: a ~ [a]
添加无限一词只是为了突出问题所在。如果类型a
与[a]
统一,那么它也会与[[a]]
,[[[a]]]
等结合使用。它永远不会与嵌套有限次数的任何列表类型统一,因为它总是可以再次展开a ~ [a]
。