2009-10-07 68 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

相關問題