[Haskell-cafe] IO in lists

Yitzchak Gale gale at sefer.org
Tue Jan 16 07:06:08 EST 2007

Magnus Therning wrote:
> Not a very descriptive subject, I know, but here's what I'd like to do.
> I can take getChar and create an infinate list:
>   listChars = getChar : listChars
> but how do I go about creating a finite list, e.g. a list that ends as
> soon as 'q' is pressed?
> I was thinking of something like
>   listChars1 = do
>       c <- lift getChar
>       if c == 'q'
>           then [return c]
>           else [return c] ++ listChars1
> However, that triggers an interesting behaviour in ghci:

<GHC's impolite choking noises deleted>

You are trying to define something of type [IO Char].

But the list monad [] is not a transformer, so you can't
lift in it, even if the contained type happens also to be
a monad.

Perhaps you are looking for something like this,
using the monad transformer version of []:

listChars2 :: ListT IO Char
listChars2 = do
  c <- lift getChar
  if c == 'q'
    then return [c]
    else return [c] `mplus` listChars2

GHC finds this much more tasty, and then

runListT listChars2

does what I think you may want.


More information about the Haskell-Cafe mailing list