2013-12-09 2 views
5

Я пытаюсь создать программу для сравнения времени, которое требуется для запуска различных сценариев haskell, которые впоследствии будут использоваться для создания графиков и отображения в графическом интерфейсе. Я попытался создать указанный графический интерфейс с использованием библиотек Haskell, но мне не повезло, тем более, что у меня возникли проблемы с поиском современных графических интерфейсов для Windows. Я попытался использовать Java для получения этих результатов, но либо получить ошибки, либо просто не получить результат.Получение результатов скрипта Haskell из 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 

В настоящее время нет никаких результатов, хранящихся или распечатанных. У кого-нибудь есть идеи?

+0

Создайте исполняемый файл сначала, а затем запустите его в 'exec' – Sibi

+0

Вам также понадобится' main' в вашем коде haskell. – Sibi

+0

Вы говорите Haskell, что '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 String, Actual type IO [String] (во втором аргументе 'fmap'). Я считал, что один скрипт Haskell выполняет все тесты и т. Д. Для каждого другого скрипта в каталоге, но не был уверен, будет ли это проще или нет. Я, вероятно, вернусь к этому, хотя, спасибо за подсказку – fylth

+0

Должна «читать карту», ​​а не читать. – sastanin

+0

Спасибо. Другой быстрый вопрос, который, как я думал, не оправдывает еще одного вопроса: используя вариацию кода, вышеописанного, я хочу прочитать два аргумента, но один из них является строкой, а другой - целым числом, однако при компиляции я получаю ошибки несоответствия типов. Есть ли способ сказать haskell читать X как Int и y как String? – fylth

0

В первый читать из вывода необходимо использовать OutputStreamReader(p.getOutputStream()) вместо InputStreamReader

2

это в основном Java вопрос. Поиск Runtime.getRuntime().exec().

На стороне Haskell вам нужно написать автономный сценарий Haskell. The one от @jozefg в порядке. Вы должны иметь возможность запускать его как

runghc /path/to/script.hs 1 2 

из командной строки.

Вызов его из Java ничем не отличается от запуска любого другого внешнего процесса на Java. В Clojure (язык виртуальной машины Java, я использую его для краткости) я:

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 просто отлично. Возможно, вам придется сменить пути к вам runghc и test.hs.

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" с ровными интерактивными графиками.

Смежные вопросы