Java 8 имеет встроенный механизм JavaScript под названием Nashorn, поэтому на самом деле можно запустить Haskell, скомпилированный в JavaScript на JVM.
Работает следующая программа:
{-# LANGUAGE JavaScriptFFI #-}
module Main where
foreign import javascript unsafe "console={log: function(s) { java.lang.System.out.print(s); }}"
setupConsole :: IO ()
foreign import javascript unsafe "java.lang.System.exit($1)"
sysexit :: Int -> IO ()
main = do
setupConsole
putStrLn "Hello from Haskell!"
sysexit 0
Мы можем запустить его с помощью: (Боковое примечание: это можно запустить как обычную программу Java. jjs
- это просто удобный способ запускать чистый код JavaScript на JVM)
$ ghcjs -o Main Main.hs
[1 of 1] Compiling Main ( Main.hs, Main.js_o )
Linking Main.jsexe (Main)
$ which jjs
~/bin/jdk/bin/jjs
$ jjs Main.jsexe/all.js
Hello from Haskell!
В приведенном выше коде console.log
необходимо определить с помощью java.lang.System.print
, поскольку Nashorn не предоставляет глобальный объект console
по умолчанию, а Haskell putStrLn
в противном случае ничего не печатает.
Другое дело, что JVM необходимо выйти с помощью функции sysexit
FFI, реализованной с помощью java.lang.System.exit
.
У меня есть 2 вопроса:
- Как и в случае с
console.log
, какие другие зависимости хоста предполагается в ghcjs, которые должны быть определены? - Является ли JVM нормально не закрываться из-за того, что ghcjs создает цикл событий в фоновом режиме или по какой-либо другой причине? Есть ли способ избежать этого и заставить программу нормально работать?