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?
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.
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.