
Magnus Therning asked:
but how do I go about creating a finite list, e.g. a list that ends as soon as 'q' is pressed?
A slightly different approach that doesn't use anything unsafe: What you want is to return something like an IO [Char] but it needs to be able to interleave IO. A list of type [Char] is essentially a solution to the equation X = Maybe (Char,X) It's either the empty list (represented by Nothing) or Just a pair of the head and tail of the list. But this doesn't allow us to intersperse IO along the computation of the list. In order to to that we need a solution to X = IO (Maybe (Char,X)) So define data X = X { unX :: IO (Maybe (Char,X)) } We can now write the 'q' terminated list as test = X $ do a <- getChar if a=='q' then return Nothing else return (Just (a,test)) For all intents and purposes, this is what you want. It reads characters until it reaches a 'q' and then returns IO Nothing. To make use of this we can write something like this to print out the contents of the list: test2 :: X -> IO () test2 test = do a <- unX test case a of Nothing -> return () Just (a,b) -> do print a test2 b 'test2 test' now prints out one of these q-terminated strings. There is a bit of clutter because of the X and unX. And it's slightly wordier because we're using Maybe instead of the nice Haskell List notation. But I think it does exactly what you want. In particular we have sepration of concerns - the object 'test' is in charge of generating data and test2 is responsible for reading it, without unsafe operations. And it seems to print the characters one at a time as they are entered (with ghc). -- Dan