GHC as a library - getting output from GHCI

Mads Lindstrøm mads_lindstroem at
Wed May 9 17:21:31 EDT 2007

Hi Simon

The Interactive.hs program do not really redirect stdout. It intercepts
calls to putStrLn and getLine via let definitions:

    mustWork "let putStrLn = MyPrelude.myPutStrLn" 
    mustWork "let getLine  = MyPrelude.myGetLine"
        -- mustWork either runs the given statement successfully or triggers an error
	where mustWork stmt = do
		result <- GHC.runStmt session stmt
		if isOk result then return () else error "replaceFunctions failed."

Thus, if GHCi's print loop is not within the context of the let
definitions, it will not use myPutStrLn and myGetLine. If I run the
Interactive.hs program on my Debian/Linux box, and write "3+4" then its
printed directly to standard output. It does not use myPutStrLn

Also if stmt =

    SomeModule.prettyPrinter "foobar"

and SomeModule contains

    prettyPrinter x = putStrLn $ "Pretty: " ++ x

then the let binding will not catch it.

Thus we have two problems. One is output from evaluating expressions
(like "3+2"), and another is output from a user module not affected by
the let-binding above. Therefore a better solution is to run "GHC as a
library" in a separate process, from which we read/write stdin, stdout,
and stderr. I am exploring several different options for running
processes in Haskell, but the only useful (for this particular purpose)
seems to be the Unix-only System.Posix.Process.

I could also use System.Process.runInteractiveCommand, which gives me
handles for stdin, stdout, stderr. But it does not seem possible to add
additional channels. Therefore control information (like getModuleGraph,
runStmt, or getBindings) must also go though stdin/stdout. It seems very
problematic to have control information, send though the same channel as
the input/output from running runStmt. For one thing the output from
runStmt can contain arbitrary data, and could therefore resemble control

Secondly, I could use Control.Concurrent. But this do not allow me to
redirect stdout, stderr or stdin.



Simon Peyton-Jones wrote: 
> | I am trying to use GHC as a library (see
> | ). I want to get all the
> | output from an interactive session and put in a GUI. This
> | seemed to be a
> | nice starting point.
> If you want to collect *all* the output, that presumably includes the output of printing to 'stdout'? That is, if I type
>         putStr "Hello"
> I see the result.
> If you manage to redirect stdout in this way, I think you will also see the value of your 'stmt', because what GHC does is to compile a little (print it) stmt and run it.
> It's a while since I looked at the Interactive loop, but I think that's right.
> Simon

More information about the Glasgow-haskell-users mailing list