
hi, it just took me an eternity to undestand a bug in my code *after* i had narrowed it down to eight lines or so. and as these bugs go, i feel very good about having found it and have to share it. although it's probably not that exciting to anybody except me. (-: here is the bug, narrowed to four lines. a function that only sometimes terminates. f = do n <- randomRIO (0,5) let l = replicate n '*' i = join $ repeat l -- infinite extension print (take 12 i) how many seconds does it take you to shout "you idiot!"? :-) spoiler below. (what would have been your fix?) cheers, matthias =================================================================== spoiler. the problem is that l is sometimes empty, and taking an element out of an infinite concatenation of empty lists takes even longer than understanding that that takes quite long. just deal with the empty-list case separately: g = do n <- randomRIO (0,5) let l = replicate n '*' i | null l = [] | otherwise = join $ repeat l print (take 12 i)

Matthias Fischmann:
g = do n <- randomRIO (0,5) let l = replicate n '*' i | null l = [] | otherwise = join $ repeat l print (take 12 i)
If you had written (cycle l) instead of (join $ repeat l), you would have figured it out much quicker. :-) Prelude> cycle [] *** Exception: Prelude.cycle: empty list

On Tue, Mar 27, 2007 at 08:02:18PM +1000, Matthew Brecknell wrote:
To: Matthias Fischmann
Cc: haskell-cafe@haskell.org From: Matthew Brecknell Date: Tue, 27 Mar 2007 20:02:18 +1000 Subject: Re: [Haskell-cafe] infinite lists Matthias Fischmann:
g = do n <- randomRIO (0,5) let l = replicate n '*' i | null l = [] | otherwise = join $ repeat l print (take 12 i)
If you had written (cycle l) instead of (join $ repeat l), you would have figured it out much quicker. :-)
Prelude> cycle [] *** Exception: Prelude.cycle: empty list
good point. and now i am learning a new word. eek! :) thanks - m

Matthias Fischmann wrote:
here is the bug, narrowed to four lines. a function that only sometimes terminates.
f = do n <- randomRIO (0,5) let l = replicate n '*' i = join $ repeat l -- infinite extension print (take 12 i)
In this paragraph I speak about just this program, ignoring that it is a lossy excerpt from another program for a different specification. This program, when corrected, will output the empty string with probability 1/6, and/or the string of twelve *'s with probability 5/6. This could be done more simply and less error-prone by writing "if n==0 then the former else the latter". In other words, I wonder why more information is produced (in the sense of information theory and entropy), only to be discarded, i.e., in 5/6 of the cases, you ask for 1 to 5 *'s, then discard that length and make them all 12. Along with the introduction of unnecessary work comes the introduction of unnecessary mistakes. In this paragraph I acknowledge that this program is a lossy excerpt from another program for a different specification. Still, if there is a sane way of mapping this program back to its origin, there is probably also some partial way of mapping my comment above to the original specification and program. I advise you to review your specification and program, and look for opportunities for eliminating unnecessary or indirect work; you may accidentally eliminate some mistakes along the way.
participants (3)
-
Albert Y. C. Lai
-
Matthew Brecknell
-
Matthias Fischmann