[Haskell-cafe] I fell in love with System.Console.Haskeline.getExternalPrint
allbery.b at gmail.com
Sun Mar 31 23:13:57 UTC 2019
You might consider that ghci is just a client of ghc-api that's built into
ghc for convenience; see the ghci-ng package on hackage, which is a
standalone version used to experiment with new ghci features. ghci itself
has a separate interpreter, in other words. (Note also
-fexternal-interpreter, which relies on this to move the backend to a
different process or even different host for cross-platform work; you might
want to look into customization at that level.)
On Sun, Mar 31, 2019 at 6:51 PM Mario Lang <mlang at delysid.org> wrote:
> Since I discovered getExternalPrint, I found a ton of use cases for it.
> In particular, it makes it possible to write background threads that
> report stuff to the console without disturbing the prompt.
> I ended up writing a sort of uGHCi with the help of hint and the
> unreleased master branch of haskeline to make externalPrint available
> from within the interpreter. Combined with Shh, this opens the door for
> a lot of useful functionality. Here is a simplified example based
> on shell programming with the help of Shh:
> % let watch r p = forkIO . forever $ printProc p >> readIORef r >>=
> % delay <- newIORef 10
> % clock <- watch delay OS.date
> Sat Mar 2 21:32:28 CET 2019
> Sat Mar 2 21:32:38 CET 2019
> % writeIORef delay 5
> Sat Mar 2 21:32:48 CET 2019
> Sat Mar 2 21:32:53 CET 2019
> Sat Mar 2 21:32:58 CET 2019
> Sat Mar 2 21:33:03 CET 2019
> % killThread clock
> printProc uses externalPrint from haskeline to print the output of a
> shell command to the console without disturbing the prompt.
> The OS module in this example simply exports all executables as haskell
> functions, thanks to the TH magic from Shh.
> I am relying on a pretty crude hack to make this work:
> (rFd, wFd) <- liftIO createPipe
> eprint <- getExternalPrint -- from haskeline
> liftIO . forkIO . forever $ do
> (s, bc) <- fdRead rFd 1024
> eprint s
> -- ...
> -- define a function in the interpreter using hint
> runStmt $ "let externalPrint s = fdWrite (read " <> show (show wFd) <>
> ") s >> pure ()"
> This hack is basically the whole magic of my own hand-rolled uGHCi.
> I'd love to not reinvent the wheel there, and just be able to use
> standard GHCi to make use of externalPrint.
> Question is, would a similar thing be possible to implement in GHCi
> directly, and if so, what would be required to make this work?
> I am likely far too much a rooky to get this working on my own, so I am
> asking for help. What steps should I follow to eventually achieve my
> goal? I guess submitting a feature request would be a start.
> However, I want progress, so I am wondering:
> * The pipe trick is likely too hacky for GHCi. Are there any other
> portable alternatives for getting data from within the interpreter to
> the haskell process running it?
> * Or is there a way to serialize an IO action into the interpreter that
> I've missed?
> The problem here is the boundary between the process that runs
> the interpreter, and the interpreter itself. I am a bit whacky on
> terminology here, but as I see it, getExternalPrint returns a function that
> has internal state. So it isn't really possible to make such a function
> available from within the interpreter. Hence, the pipe hack above,
> which just sends the *argument* to externalPrint from the interpreter to
> the process running it.
> Any insights that might help me make that available in standard
> GHCi? I really think this is a pretty unique feature that would enable
> all sorts of interesting interactive code.
>  Haskeline < 0.8.0 doesn't allow to combine IntterpreterT from hint
> with InputT because of the way exceptions are done. The master branch
> of haskeline fixes that, so finally you can have a transformer stack
> that combines both, allowing for pretty simple interactive haskell
> interpreters with readline functionality. Thanks for that!
> Haskell-Cafe mailing list
> To (un)subscribe, modify options or view archives go to:
> Only members subscribed via the mailman list are allowed to post.
brandon s allbery kf8nh
allbery.b at gmail.com
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the Haskell-Cafe