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?

+2


source to share


2 answers


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.

+7


source


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.

+8


source







All Articles