Ответ 1
С помощью luite я наконец-то начал работать с немного прокладки для JVM:
-
Определение платформы (планки/src/platform.js)
Java Nashorn предоставляет глобальную переменную
Java
, которая может использоваться для определения того, работаем ли мы под JVM. Если эта переменная определена, глобальная переменнаяh$isJvm
устанавливается аналогичноh$isNode
для времени выполнения ghcjs. Затем эта переменная будет использоваться для предоставления JVM-кода в других местах. Мы также можем определитьconsole.log
здесь, чтобы запись в консоль работала из коробки в JVM без необходимости определять ее в пользовательской программе:if(typeof Java !== 'undefined') { h$isJvm = true; this.console = { log: function(s) { java.lang.System.out.print(s); } }; }
-
Выход из JVM обычно (прокладки/src/thread.js)
GHCJS имеет метод под названием
h$exitProcess
, который используется для выхода из процесса. С переменной, определенной на предыдущем шаге,h$isJvm
, мы можем добавить следующий код для выхода JVM:if (h$isJvm) { java.lang.System.exit(code); }
-
Аргументы командной строки (прокладки/src/environment.js)
Nashorn предоставляет глобальную переменную
arguments
, которая содержит значения параметров командной строки, переданные вjjs
. Мы можем добавить прокладку, используя эту переменную:if(h$isJvm) { h$programArgs = h$getGlobal(this).arguments; }
С этими прокладками мы можем запустить большую часть Haskell из коробки на JVM. Вот исходная программа в вопросе с вышеуказанными прокладками, добавленными в GHCJS:
module Main where
main = putStrLn "Hello from Haskell!"
Этот обычный код Haskell теперь запускается из коробки в JVM. Даже небольшие нетривиальные функции запускаются непосредственно на JVM. Например, следующий код, взятый из здесь:
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE OverloadedStrings #-}
import Options.Generic
data Example = Example { foo :: Int, bar :: Double }
deriving (Generic, Show)
instance ParseRecord Example
main = do
x <- getRecord "Test program"
print (x :: Example)
Мы можем построить его с помощью stack
и запустить с помощью jjs
прохождение аргументов командной строки:
haskell-jvm-hello$ stack build
haskell-jvm-hello$ jjs ./.stack-work/dist/x86_64-linux/Cabal-1.22.4.0_ghcjs/build/haskell-jvm-hello-exe/haskell-jvm-hello-exe.jsexe/all.js -- --help
Test program
Usage: a.js --foo INT --bar DOUBLE
Available options:
-h,--help Show this help text
haskell-jvm-hello$ jjs ./.stack-work/dist/x86_64-linux/Cabal-1.22.4.0_ghcjs/build/haskell-jvm-hello-exe/haskell-jvm-hello-exe.jsexe/all.js -- --foo 1 --bar 2.5
Example {foo = 1, bar = 2.5}