为什么Haskell抛出'无法构造无限类型'错误?

时间:2009-10-07 09:54:43

标签: haskell type-inference

我在Haskell中编写了以下代码来计算两个向量的点积,但由于以下错误而无法编译它:

cannot construct infinite type: a = [a] When generalising the type(s) for dot'

dot :: (Num a) => [a] -> [a] -> a

[] `dot` [] = 0
x@[xi,xs] `dot` y@[yi,ys] = xi*yi + (xs `dot` ys)

我事先看了this question寻求指导。据我所知,类型是正确的。 x,y和两个[]是列表,函数返回一个数字。

怎么了?

2 个答案:

答案 0 :(得分:8)

Ganesh' answer现场点亮。让我简要阐述一下“无限型”的含义。

dot具有此类型定义:

dot :: (Num a) => [a] -> [a] -> a

这意味着dot会收集两个Num元素列表并返回Num。您的定义包括以下这一行:

x@[xi,xs] `dot` y@[yi,ys] = xi*yi + (xs `dot` ys)

正如Ganesh指出的那样,[xi,xs]是一个由两个元素组成的列表,xixs应该是Num s。 yiys也是如此。但随后它们作为参数传递给dot

xs `dot` ys

这意味着xsys必须是Num的列表。这导致了矛盾。


另一种看待这种情况的方法是暂时忘记dot的类型定义。这一行,

x@[xi,xs] `dot` y@[yi,ys] = xi*yi + (xs `dot` ys)

指出dot采用两个列表,其元素是dot的适当参数。但唯一有意义的方法是,这些列表是无限嵌套。这是不允许也不明智的。

答案 1 :(得分:7)

您将两个元素列表[x, y]的语法与将列表拆分为第一个元素和列表(x:y)的其余部分的语法混淆。试试这个:

dot :: (Num a) => [a] -> [a] -> a

[] `dot` [] = 0
x@(xi:xs) `dot` y@(yi:ys) = xi*yi + (xs `dot` ys)

@模式也是不必要的,顺便说一句。