2009-10-07 34 views
2

我写了下面的代码在Haskell计算两个向量的点积,但无法将其编译由于以下错误:为什么Haskell抛出'无法构造无限类型'的错误?

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

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

[] `dot` [] = 0 
[email protected][xi,xs] `dot` [email protected][yi,ys] = xi*yi + (xs `dot` ys) 

我已经提前采取一看this question为指导。据我所知,类型是正确的。 x,y和两个[]是列表,并且该函数返回一个数字。

怎么了?

+2

这就是对象引用没有设置或堆栈溢出的哈斯克尔等价物,你会看到它很多;) – 2009-10-07 09:59:12

回答

7

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

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

[] `dot` [] = 0 
[email protected](xi:xs) `dot` [email protected](yi:ys) = xi*yi + (xs `dot` ys) 

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

+0

非常感谢,这没有办法。 – Zaid 2009-10-07 10:13:36

8

Ganesh' answer是现货。让我简单地说一下“无限类型”的含义。

dot具有此类型定义:

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

这意味着dot需要Num元件的两个列表,并返回一个Num。你的定义包括这行:

[email protected][xi,xs] `dot` [email protected][yi,ys] = xi*yi + (xs `dot` ys) 

因为如Ganesh神指出,[xi,xs]是由两个元素,xixs应该是Num的List。 yiys也是如此。但随后他们被作为参数传递给dot

xs `dot` ys 

这意味着xsys必须是Num小号名单。这导致矛盾。


另一种看待这个问题的方法是暂时忘掉dot的类型定义。这条线,

[email protected][xi,xs] `dot` [email protected][yi,ys] = xi*yi + (xs `dot` ys) 

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

+0

@Stephan:谢谢你的解释。我认为这清除了为什么即使[xi:xs]表示法失败,因为xs'dot'意味着xs和ys是列表清单... 让我知道我的解释是否有效。 – Zaid 2009-10-07 11:34:41

+0

@Zaid:那是对的。如果'xi :: a',那么'(xi:xs):: [a]'和'[xi:xs] :: [[a]]'。因此,匹配'[xi:xs]'然后递归传递'xs'确实会导致*无限类型*错误。 – Stephan202 2009-10-07 11:47:55

相关问题