2013-12-09 3 views
5

나는 다양한 haskell 스크립트를 실행하는 데 걸리는 시간을 비교하기 위해 프로그램을 만들려고하는데, 나중에 그래프를 만드는 데 사용되며 GUI에 표시됩니다. 하스켈 라이브러리를 사용하여 GUI를 만들려고했으나 Windows 용 GUI 라이브러리를 최신으로 찾는 데 어려움을 겪고 있습니다. 자바를 사용하여 이러한 결과를 얻으려고 시도했지만 오류가 반환되거나 단순히 결과가 표시되지 않습니다.자바에서 하스켈 스크립트의 결과 얻기

내가 지금 뭘하는지 대략 보여줄 수있는 최소한의 예를 구축했습니다

: 여기

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(); 
     } 
    } 
} 

그리고 이것을 호출하는 하스켈 스크립트는 간단한 또한이 경우에

test x y = x + y 

현재 저장되거나 인쇄 된 결과가 없습니다. 누구든지 아이디어가 있습니까?

+0

먼저 실행 파일을 만든 다음'exec'에서 실행하십시오. – Sibi

+0

또한 haskell 코드에'main'이 필요합니다. – Sibi

+0

당신은 하스켈에게'test x y'가'x + y'와 동일하다고 말하고 있습니다. 당신은 어떤 결과물을 기대합니까? – Ingo

답변

3

실행 파일로 실행하려고 했으므로 메인을 제공해야합니다. 이 경우에는 다음과 같이 표시되어야합니다.

import System.Environment 

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

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

이것은 명령 줄 인수를 읽고 추가 한 다음 인쇄합니다. 비록 내가 얼마전에했던 일이지만 Haskell에서 벤치마킹/테스팅을하는 것이 훨씬 쉽고 출력 데이터를 더 구조화 된 형식으로 텍스트 파일에 덤핑 한 다음 Java 또는 원하는 언어로 구문 분석/표시 할 수 있습니다. 출력에서 읽을 먼저

+0

컴파일 중 오류가 발생했습니다 : [Char] 유형을 Char, 예상 유형 IO 문자열, 실제 유형 IO [String] ('fmap'의 두 번째 인수)와 일치시킬 수 없습니다. 하나의 Haskell 스크립트가 디렉토리의 각 스크립트에 대해 모든 벤치마킹 등을 수행하는 것으로 생각했지만,이 방법보다 단순한 것인지 확실하지 않았습니다. 그래도 팁으로 돌아가서 고맙겠습니다. – fylth

+0

'read'가 아니라'map read'를해야합니다. – sastanin

+0

감사합니다. 위에서 언급 한 코드의 변형을 사용하면 두 개의 인수를 읽으려고 하나는 문자열이고 다른 하나는 정수이지만 컴파일 할 때 형식 불일치 오류가 발생합니다. iskell에 X를 Int로, y를 String으로 읽는 방법을 알려줄 수 있습니까? – fylth

0

는 대신 InputStreamReader

2

이 주로 자바 질문의 OutputStreamReader(p.getOutputStream())를 사용해야합니다. Runtime.getRuntime().exec()을 검색하십시오.

하스켈 측에서 독립형 하스켈 스크립트를 작성해야합니다. @jozefg의 The one은 정상입니다. 명령 줄에서

으로 실행할 수 있어야합니다.

Java에서 호출하는 것은 Java의 다른 외부 프로세스를 실행하는 것과 같습니다. Clojure의 나는 할 (A 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") 

내가 스크립트 (하지 ghc)를 실행하는 runghc를 사용하는 것이 있습니다. 전체 경로는 필요하지 않지만 도움이 될 수 있습니다. 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; 

수정 된 버전은 하스켈 스크립트를 정상적으로 실행합니다. runghctest.hs 위치로 경로를 변경해야 할 수 있습니다.

0

의견에서 언급했듯이 그러한 벤치 마크는 단순히 부정확합니다. 벤치마킹하는 동안 최대한 많은 측면 해안을 제거해야합니다. 가장 좋은 해결책은 criterion 패키지를 사용하는 것입니다. 원하는대로 멋진 그래픽 출력물을 생성합니다.

작은 예 : 그것은 깔끔한 대화 형 플롯을 가진 파일 "report.html"를 생산

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 
      ] 

실행 후.