简体   繁体   English

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

[英]Why is Haskell throwing a 'cannot construct infinite type' error?

I wrote the following code in Haskell to compute the dot product of two vectors, but cannot compile it due to the following error: 我在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)

I've taken a look at this question in advance for guidance. 我事先看过这个问题以获得指导。 As far as I can tell, the types are correct. 据我所知,类型是正确的。 x, y and the two []'s are lists, and the function returns a number. x,y和两个[]是列表,函数返回一个数字。

What's wrong? 怎么了?

Ganesh' answer is spot on. Ganesh的回答很明显。 Let me briefly elaborate on the meaning of an "infinite type". 让我简要阐述一下“无限型”的含义。

dot has this type definition: dot有这种类型定义:

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

This means that dot takes two lists of Num elements and returns a Num . 这意味着dot需要两个Num元素列表并返回Num Your definition includes this line: 您的定义包括以下行:

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

Since, as Ganesh points out, [xi,xs] is a list consisting of two elements, xi and xs should be Num s. 因为,正如Ganesh指出的那样, [xi,xs]是由两个元素组成的列表, xixs应该是Num s。 Same for yi and ys . 对于yiys But then they are passed as arguments to dot : 但随后它们作为参数传递给dot

xs `dot` ys

This means that xs and ys must be lists of Num s. 这意味着xsys必须是Num s的列表。 That leads to a contradiction. 这导致了矛盾。


Another way to look at this, is to for a moment forget about the type definition of dot . 另一种看待这种情况的方法是暂时忘记dot的类型定义。 This line, 这条线,

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

states that dot takes two lists whose elements are appropriate arguments to dot . 表示dot采用两个列表,其元素是dot适当参数。 But the only way for that to make sense, is if these lists are infinitely nested . 但唯一有意义的方法是,这些列表是否是无限嵌套的 That is not allowed nor sensible. 这是不允许也不明智的。

You're confusing the syntax for a two element list [x, y] with the syntax for splitting a list into the first element and the rest of the list (x:y) . 您将两个元素列表[x, y]的语法与将列表拆分为第一个元素和列表的其余部分(x:y)的语法混淆。 Try this instead: 试试这个:

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

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

The @ patterns are also unnecessary, btw. @模式也是不必要的,顺便说一下。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM