Why is Haskell throwing the "can't build infinite type" error?
I wrote the following code in Haskell to calculate the dot product of two vectors, but I cannot compile it due to the following error:
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 went over this question beforehand for guidance. As far as I can tell, the types are correct. x, y and two [] are lists, and the function returns a number.
What's wrong?
source to share
You are misleading the syntax for a list of two elements [x, y]
with a syntax for splitting the list into the first element and the rest of the list (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)
@
No templates needed either, btw.
source to share
Ganesh's answer is in place. Let me briefly explain the meaning of "infinite type".
dot
has a definition of this type:
dot :: (Num a) => [a] -> [a] -> a
This means it dot
takes two lists of elements Num
and returns a Num
. Your definition includes this line:
x@[xi,xs] `dot` y@[yi,ys] = xi*yi + (xs `dot` ys)
Since, as Ganesh points out, it [xi,xs]
is a list of two elements xi
and xs
should be Num
s. The same for yi
and ys
. But then they are passed as arguments dot
:
xs `dot` ys
This means that xs
and ys
must be lists of Num
s. This leads to a contradiction.
Another way to look at this is to forget about the type definition for a minute dot
. This line,
x@[xi,xs] `dot` y@[yi,ys] = xi*yi + (xs `dot` ys)
claims to dot
accept two lists, whose elements are valid arguments for dot
. But the only way it makes sense for this is if these lists are infinitely nested. This is unacceptable and reasonable.
source to share