我正在研究Haskell presentation engine Howerpoint。它在GHCi中运行。我想创建一个函数,它将一个语句输出到当前运行的GHCi会话。它必须适用于Linux和Mac,Windows不是必需的。函数可能有类型
executeStatement :: String -> IO ()
我已经尝试过了:
getProcessID
和getParentProcessID
然后发送类似
echo 'xxx' > /proc/92856/fd/1
-bash: /proc/92856/fd/1: No such file or directory
我也试过runCommand
但它在Bash中执行命令而不是在GHCi中执行命令所以我收到错误命令找不到
xdotool
无法在Mac上运行
答案 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。