The List.partition function has the specification
partition :: (a -> Bool) -> [a] -> ([a],[a])
partition p xs == (filter p xs, filter (not . p) xs)
(see the Haskell98 report) but its implementation (also there)
partition p xs = foldr select ([],[]) xs
where select x (ts,fs) | p x = (x:ts,fs)
| otherwise = (ts, x:fs)
is too strict, as seen by evaluating
let (a,b)= partition odd [1::Int ..] in print (take 3 a,take 3 b)
which should give ([1,3,5],[2,4,6]). Both ghc-4.08 and hugs98-Feb-2000
(PS: methinks the hugs version numbering scheme is ugly ugly ugly :)
report stack overflow. However nhc98-1.0pre19 gets it right:
because it has a "~" right before the (ts,fs) binding.
Still, this is not a nice state of affairs.
How can we reason formally about whether we need a pattern to be lazy,
or about "black holes"? In Hudak's SOE book, it's in section 14.4,
in an "experimental" fashion. Perhaps this approach is best suited
for teaching: it exemplifies the problem, and shows a solution;
but I'd like to have some formal tools
that a) warn me that the problem could occur
or rather b) prove that the "solution" really prevents it.
Are there extensions of the type system that would be helpful?
Best regards,
--
-- Johannes Waldmann ---- http://www.informatik.uni-leipzig.de/~joe/ --
-- [EMAIL PROTECTED] -- phone/fax (+49) 341 9732 204/252 --
===> Drittes Leipziger Jongliertreffen 6. - 8. Oktober <===
===> http://www.informatik.uni-leipzig.de/~joe/juggling/dreilei/ <===