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

Reply via email to