I am not a Haskell pro. Today I had a somewhat bizarre experience with the type system today. The second line of this will cause a type error. The problem is the maxdiag (as:bs:cs:ds) bit of the second line:
maxdiag ((a:as):(b:bs):(c:cs):(d:ds):xs) len =
maximum [a*(bs !! 0)*(cs !! 1)*(ds !! 2), maxdiag (as:bs:cs:ds) (len-1)]
It fails with the following error:
Occurs check: cannot construct the infinite type: a0 = [a0]
Expected type: [[a0]]
Actual type: [a0]
In the second argument of `(:)', namely `ds'
In the second argument of `(:)', namely `cs : ds'
When I change the offending part of the second line to maxdiag (as:bs:cs:ds:xs), so that it reads
maxdiag ((a:as):(b:bs):(c:cs):(d:ds):xs) len =
maximum [a*(bs !! 0)*(cs !! 1)*(ds !! 2), maxdiag (as:bs:cs:ds:xs) (len-1)]
… then there is no error. Similarly, if I replace it with maxdiag (as:bs:cs:(ds:xs)) it succeeds. My questions are
- What does this error mean?
- Why has it occurred?
- Why do these two seemingly different things fix it?
The thing to remember is that
(:)has the typea -> [a] -> [a], so its first argument is an element, while the second argument is a list with that element type. If the elements are themselves lists, this becomes[a] -> [[a]] -> [[a]].In your example,
as,bs,csanddsall have type[a], whilexshas type[[a]], socs:dsis an error whileds:xsis well-typed.The reason for that particular error message is that when you try to use
(:)on two things of the same typeb, the only way that would work is ifbwas the same type as[b], but that would be an infinite type which is not allowed.For the other question, the
(:)operator is right-associative, soas:bs:cs:ds:xsis the same asas:(bs:(cs:(ds:xs)))and alsoas:bs:cs:(ds:xs).