如何将文本发送到GHCi流程?

时间:2016-02-11 05:54:50

标签: haskell ghci

我正在研究Haskell presentation engine Howerpoint。它在GHCi中运行。我想创建一个函数,它将一个语句输出到当前运行的GHCi会话。它必须适用于Linux和Mac,Windows不是必需的。函数可能有类型

executeStatement :: String -> IO ()

我已经尝试过了:

  • getProcessIDgetParentProcessID然后发送类似

    的内容
    echo 'xxx' > /proc/92856/fd/1
    -bash: /proc/92856/fd/1: No such file or directory
    
  • 我也试过runCommand但它在Bash中执行命令而不是在GHCi中执行命令所以我收到错误命令找不到

  • xdotool无法在Mac上运行

2 个答案:

答案 0 :(得分:2)

您可以使用tmux之类的终端多路复用器在一个窗格中执行 ghci ,并从另一个窗格调用 tmux 命令,将命令发送到 ghci中

tmux load-buffer允许您将文本加载到tmux剪贴板中(使用-作为路径从stdin读取)。

# from within tmux
$ echo foo | tmux load-buffer -
$ tmux show-buffer
foo

tmux paste-buffer允许您将tmux剪贴板的内容粘贴到窗格中:

$ tmux list-panes
0: [127x24] [history 1850/2000, 1343570 bytes] %0
1: [127x24] [history 0/2000, 0 bytes] %2 (active)
$ tmux paste-buffer -t %0

评论中已经提到的另一个选项是使用process库来启动ghci进程,并通过管道标准输入发送命令。

这是一个小程序,它使用我的process-streaming帮助程序包进行进程(不是真的需要,您可以单独使用进程执行相同操作)。管道 stdin stdout stderr 继承:

{-# LANGUAGE OverloadedStrings #-}

import System.Process.Streaming -- from process-streaming
import Pipes (lift,yield) -- from pipes
import Control.Concurrent (threadDelay)

main :: IO ()
main = executeInteractive program (feedProducer (do
    let delay = lift (threadDelay (1000000*6))
    delay
    yield "4 + 3\n"
    delay
    yield "5 + 3\n"))
  where
    program = (shell "ghci"){ std_in = CreatePipe }

输出结果为:

$ ./Main
GHCi, version 7.10.2: http://www.haskell.org/ghc/  :? for help
Prelude> 7
Prelude> 8
Prelude> Leaving GHCi.

答案 1 :(得分:2)

您可以使用hackage中的ghcid项目来评估表达式。它们不会在当前运行的同一会话中进行评估,但您仍可以在 a 会话中发送表达式并读取其输出。 这是一个例子:

import Language.Haskell.Ghcid

main :: IO ()
main = do 
    (g, _) <- startGhci "ghci" (Just ".") True 
    let executeStatement = exec g
    executeStatement "let x = 33"
    executeStatement "x + 8" >>= print . head
    executeStatement "print x" >>= print . head
    stopGhci g

输出为“41”“33”,g代表ghci会话。

如果你真的需要在已经运行的ghci实例中执行表达式,你可以查看这个函数 - startGhci而不是创建一个新进程,你必须使用现有进程,然后设置std_in ,std_out和std_err。