I am new to Haskell and facing a "cannot construct infinite type" error that I cannot make sense of.
In fact, beyond that, I have not been able to find a good explanation of what this error even means, so if you could go beyond my basic question and explain the "infinite type" error, I'd really appreciate it.
Here's the code:
intersperse :: a -> [[a]] -> [a]
-- intersperse '*' ["foo","bar","baz","quux"]
-- should produce the following:
-- "foo*bar*baz*quux"
-- intersperse -99 [ [1,2,3],[4,5,6],[7,8,9]]
-- should produce the following:
-- [1,2,3,-99,4,5,6,-99,7,8,9]
intersperse _ [] = []
intersperse _ [x] = x
intersperse s (x:y:xs) = x:s:y:intersperse s xs
And here's the error trying to load it into the interpreter:
Prelude> :load ./chapter.3.ending.real.world.haskell.exercises.hs
[1 of 1] Compiling Main (chapter.3.ending.real.world.haskell.exercises.hs, interpreted )
chapter.3.ending.real.world.haskell.exercises.hs:147:0:
Occurs check: cannot construct the infinite type: a = [a]
When generalising the type(s) for `intersperse'
Failed, modules loaded: none.
Thanks.
--
Here is some corrected the code and a general guideline for dealing with the "infinite type" error in Haskell:
Corrected code
intersperse _ [] = []
intersperse _ [x] = x
intersperse s (x:xs) = x ++ s:intersperse s xs
What the problem was:
My type signature states that the second parameter to intersperse is a list of lists. Therefore, when I pattern matched against "s (x:y:xs)", x and y became lists. And yet I was treating x and y as elements, not lists.
Guideline for dealing with the "infinite type" error:
Most of the time, when you get this error, you have forgotten the types of the various variables you're dealing with, and you have attempted to use a variable as if it were some other type than what it is. Look carefully at what type everything is versus how you're using it, and this will usually uncover the problem.
a
, any of which would be fine in isolation. So it can't point to any one of them and say "that's an unsupported operation for this type". But together they add up to a requirement for a type satisfyinga = [a]
. The compiler knows that is impossible, so it tells you that. It doesn't know which parts of the code that led to that requirement are the wrong parts; that depends on what you intended the code to mean. – Ben