[Haskell-cafe] Re: IO in lists

Yitzchak Gale gale at sefer.org
Sun Jan 28 05:56:56 EST 2007


Hi Magnus,

You wrote:
> This piece has type problems.  I couldn't get ghci to
> accept it without making some changes...

You are absolutely correct, and I apologize for the errors.
I will try one more time to give a corrected version below.

Let me point out, though, that this does not exactly solve the
problem you originally stated. Here is a summary and
clarification of what we have come up with together so far:

First, I said that it sounds like what you really want is ListT.

But you pointed out that my ListT solution gave you the wrong
order of interaction.

The reason for this problem is a bug in the implementation
of ListT in the standard libraries, which is explained on the
wiki page:

http://www.haskell.org/haskellwiki/ListT_done_right

Dan Piponi posted a solution to your problem that works
the way you want it, and without unsafeInterleaveIO.
Dan's solution is just ListT in disguise, except that Dan
used the corrected form of ListT like on the wiki page.

My code in which you found the errors is a translation
of Dan's solution back into ListT notation. So if you
use that with the broken ListT currently in the standard
libraries, you'll go back to the problem we had at the
beginning.

Here is the bottom line:

You can solve your problem - without unsafeInterleaveIO -
either by using one of the corrected versions of ListT
listed on the wiki page, or by writing out an implementation
of ListT that is hard-wired for your application like Dan
did.

OK, so here is my translation of Dan's code back
into ListT notation again. I hope this version is now correct:

test = do
 a <- liftIO getChar
 guard $ a /= 'q'
 return a `mplus` test

test2 = (>>= liftIO . print)

Run it with:

runListT $ test2 test

Note that you probably want putChar instead of print.
Also, Dan's version drops the 'q' at the end, while
your code prints the 'q'.

Hope this helps.

Regards,
Yitz


More information about the Haskell-Cafe mailing list