从Java获取Haskell脚本的结果

时间:2013-12-09 15:22:26

标签: java haskell

我正在尝试创建一个程序来比较运行各种haskell脚本所需的时间,稍后将用于创建图形并在GUI中显示。我曾尝试使用Haskell库创建所述GUI,但我没有太多运气,特别是因为我无法找到最新的Windows GUI库。我曾尝试使用Java来获取这些结果,但要么返回错误,要么根本没有结果。

我构建了一个最小的例子来大致展示我现在正在做的事情:

    import java.io.*;
public class TestExec {
    public static void main(String[] args) {
        try {
            Process p = Runtime.getRuntime().exec("ghc test.hs 2 2");
            BufferedReader in = new BufferedReader(
                                new InputStreamReader(p.getInputStream()));
            String line = null;
            while ((line = in.readLine()) != null) {
                System.out.println(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

这是调用的Haskell脚本,在这种情况下是一个简单的补充:

test x y =  x + y

目前根本没有存储或打印任何结果。有人有什么想法吗?

4 个答案:

答案 0 :(得分:3)

由于您尝试将其作为可执行文件运行,因此需要提供main。在你的情况下它应该看起来像

import System.Environment

test :: Integer -> Integer -> Integer
test = (+)

main = do
  [x, y] <- map read `fmap` getArgs
  print $ x `test` y

这只是读取命令行参数,添加它们,然后打印它们。虽然我做了类似的事情,但是在Haskell中进行基准测试/测试要容易得多,并且以更结构化的格式将输出数据转储到文本文件中,然后用Java或任何你喜欢的语言解析/显示它。 / p>

答案 1 :(得分:2)

这主要是一个Java问题。搜索Runtime.getRuntime().exec()

在Haskell方面,您需要编写一个独立的Haskell脚本。 @jozefg的The one没问题。您应该可以将其作为

运行
runghc /path/to/script.hs 1 2
从命令行

从Java调用它与在Java中运行任何其他外部进程没什么不同。在Clojure(一种JVM语言,我简单地使用它)我做:

user=> (def p (-> (Runtime/getRuntime) (.exec "/usr/bin/runghc /tmp/test.hs 1 2")))
#'user/p
user=> (-> p .getInputStream input-stream reader line-seq)
("3")

请注意,我使用runghc来运行脚本(不是ghc)。完整路径不是必需的,但可能会有所帮助。您的Java程序可以通过以下方式进行修改:

--- TestExec.question.java
+++ TestExec.java
@@ -2,7 +2,7 @@
 public class TestExec {
     public static void main(String[] args) {
         try {
-            Process p = Runtime.getRuntime().exec("ghc test.hs 2 2");
+            Process p = Runtime.getRuntime().exec("/usr/bin/runghc /tmp/test.hs 2 2");
             BufferedReader in = new BufferedReader(
                                 new InputStreamReader(p.getInputStream()));
             String line = null;

修改后的版本运行Haskell脚本就好了。您可能需要更改runghctest.hs位置的路径。

答案 2 :(得分:0)

首先要从输出中读取,您需要使用OutputStreamReader(p.getOutputStream())而不是InputStreamReader

答案 3 :(得分:0)

正如我在评论中所说,这样的基准是完全错误的。基准测试应尽可能消除尽可能多的侧滑。最好的解决方案是使用criterion包。它可以根据需要生成漂亮的图形输出。

小例子:

import Criterion
import Criterion.Main
import Criterion.Config

fac 1 = 1
fac n = n * (fac $ n-1)

myConfig = defaultConfig {
              cfgReport = ljust "report.html"
             }

main = defaultMainWith myConfig (return ()) [
           bench "fac 30" $ whnf fac 30
          ]

执行后,它会生成一个带有整洁交互式图表的文件“report.html”。