[Haskell-beginners] Defeating type inference
Philip Scott
pscott at foo.me.uk
Wed Feb 25 19:18:15 EST 2009
Well, either that or I being an idiot.
Here's a little example. Let us say you had a datatype 'Month'*
data Month = Jan
| Feb
| Mar
| Apr
| May
| Jun
| Jul
| Aug
| Sep
| Oct
| Nov
| Dec
deriving(Show, Eq, Ord, Ix)
What I would like to make is an infinite lazy list of months (called,
rather imaginitively I thought, 'months') that keeps wrapping around.
That is to say, it would make a list like this
[Jan, Feb, ...., Nov, Dec, Jan, Feb, ....., Nov, Dec, ... ad infinitum ]
I am sure you get the picture. My first stab was this:
months = range (Jan, Dec) : months
But of course, what you get here is a list of lists, with each element
being a list of [Jan, Feb, ...., Dec]
So I puzzled for a little bit about how to do this in the most Haskelly
way and I thought of this
months = concat (range (Jan, Dec) : months)
Which should work, right**
But the type checker is not pleased at all and complains:
Couldn't match expected type `[Month]'
against inferred type `Month'
Expected type: [[Month]]
Inferred type: [Month]
In the expression: concat (range (Jan, Dec) : months)
In the definition of `months':
months = concat (range (Jan, Dec) : months)
However, if you use the first definition and make a second function:
months = range (Jan, Dec) : months
realmonths = concat(months)
It is happy and does what one might expect. I thought perhaps I was just
confusing the inference engine so I tried a liberal sprinkling of ::
operators to make my intentions clear, but it still wasn't having any of it.
Any thoughts welcomed!
- Philip
* I am aware that there is plenty of code to handle dates and times
already written, probably much more nicely than mine - this is just a
project I have been hacking at to get to grips with things.
** though I am pretty sure this is the Wrong Way to do this. I suspect
concat takes O(n) time - more elegant approaches would be welcomed!
More information about the Beginners
mailing list