On Mon, Sep 25, 2000 at 05:17:15PM +0200, Jose Emilio Labra Gayo wrote:
> I had an interactive program which used a function of type
> > prg :: String -> String
> > prg =
> > {- for example -} \(c:cs) -> "first char = " ++ [c]
> To run that program I used
> > run :: IO ()
> > run = interact prg
> Now, I want to reuse that function in a shell program which will
> execute the interactive function more than once (as an example,
> suppose that the shell program executes 'run' twice)
> > main = run >> run
> However, after the first run, stdin gets semi-closed, and the second
> run fails with an Illegal operation.
You can't do this directly for the reasons you state. Here are two
options:
1. If you know offhand what will divide the first set of input from
the next then write a function with signature:
split :: String -> (String, String)
which returns the first half and the second half. Then you do
this:
main = do (f, s) <- split getContents
putStr (prg f)
putStr (prg s)
2. If you do not know what will split your input, you'll have to
modify your prg function to have this signature:
prg :: String -> (String, String)
Where the first part of the result is the result calculated, the
second is the remainder of the input stream. Then main could look
like this:
main = do (rs, rm) <- prg getContents
putStr rs
(rs', _) <- prg rm
putStr rs'
It's not as pretty, but it will get you what you want.
Note: I haven't tried any of this :)
--
-- Jeffrey Straszheim | A sufficiently advanced
-- Systems Engineer, Programmer | regular expression is
-- http://www.shadow.net/~stimuli | indistinguishable from
-- stimuli AT shadow DOT net | magic