Un compilador para generar código JavaScript de Haskell.
Incluso tiene un sitio web y una lista de correo.
Tiene tres opciones para apresurarse: instalar desde Hackage, desde Github o de uno de los paquetes binarios preconstruidos. En los dos primeros casos, debe agregar el directorio de Bin de adición Cabal, generalmente ~/.cabal/bin , a su $PATH si aún no lo ha hecho. Al instalar desde la Mac, Windows portátil o el paquete genérico de Linux, es posible que desee agregar path/to/haste-compiler/bin a su $PATH . El paquete Debian, así como el instalador de Windows y el script de instalación opcional incluido en el paquete genérico de Linux, se encargan de esto automáticamente.
O puede instalar la última versión estable de Hackage:
$ cabal install haste-compiler
$ haste-boot
Construir desde GitHub Source es igualmente fácil. Después de revisar la fuente, cd al árbol de origen y ejecute:
$ cabal install
$ haste-boot --force --local
Alternativamente, también puede construir desde GitHub Source usando Stack:
$ stack install
$ haste-boot --force --local
Consulte doc/building.md para obtener más información sobre los requisitos y procedimientos de compilación para las diversas plataformas.
Si tiene problemas con el haste-cabal instalado por haste-boot , puede intentar construirlo desde cero y luego pasar la bandera --no-haste-cabal a haste-boot :
$ git clone https://github.com/valderman/cabal.git
$ cd cabal && git checkout haste-cabal
$ cd Cabal && cabal install
$ cd ../cabal-install && cabal install
Al instalar Haste desde GitHub, probablemente debería ejecutar la suite de prueba primero, para verificar que todo esté funcionando. Para hacer eso, ejecute ./runtests.sh en el directorio de la raíz de prisa. También puede ejecutar solo una prueba en particular ejecutando ./runtests.sh NameOfTest . El conjunto de pruebas usa el intérprete nodejs de forma predeterminada, pero esto puede modificarse configurando la variable de entorno JS como tal: JS=other-js-interpreter ./runtests.sh . Otros intérpretes de JavaScript pueden o no funcionar. runtests.sh no se descarga al instalar desde Hackage. Tendrías que descargarlo de GitHub.
Para construir el compilador de cierre parcheado utilizado al compilar usando --opt-minify , obtenga la fuente de cierre, aplique patches/closure-argument-removal.patch y construya como lo haría normalmente. Sin embargo, esto generalmente no es necesario, ya que haste-boot obtiene un binario de cierre precompilado cuando se ejecuta.
Para obtener instrucciones de compilación más detalladas, consulte doc/building.md .
Se ha probado Haste para trabajar en las plataformas Windows y OSX, pero se desarrolla principalmente en GNU/Linux. Como tal, ejecutar en una plataforma GNU/Linux probablemente le obtendrá menos errores.
Para compilar su programa Haskell a un blob de JavaScript listo para ser incluido en un documento HTML o ejecutar utilizando un intérprete de línea de comandos:
$ hastec myprog.hs
Esto es equivalente a llamar a GHC - -MyProg.hs; Main.Main será llamado tan pronto como el JS Blob haya terminado de cargarse.
Puedes pasar las mismas banderas a Hastec, ya que normalmente pasarías a GHC:
$ hastec -O2 -fglasgow-exts myprog.hs
Haste también tiene su propio conjunto de argumentos de línea de comandos. Invírelo con --help para leer más sobre ellos. En particular, --opt-all , --opt-minify , --start y --with-js debe ser bastante interesante.
Si desea que su paquete se compile tanto con prisa como, digamos, GHC, es posible que desee usar la extensión CPP para la compilación condicional. La prisa define el símbolo del preprocesador __HASTE__ en todos los módulos que compila. Este símbolo también se puede usar para diferenciar entre versiones de prisa, ya que se define como una representación entera de la versión de prisa actual. Su formato es MAJOR*10 000 + MINOR*100 + MICRO . La versión 1.2.3 se representaría como 10203 y 0.4.3 como 403.
Haste también viene con envoltorios para Cabal y GHC-PKG, llamado Saste-Cabal y Saste-PKG respectivamente. Puede usarlos para instalar paquetes tal como lo haría con Vanilla GHC y Cabal:
$ haste-cabal install mtl
Finalmente, puede interactuar con el código JavaScript utilizando el módulo Haste.Foreign en la biblioteca haste-lib Bundled. Consulte doc/js-externals.txt para obtener más información al respecto. Esta biblioteca también contiene todo tipo de funcionalidad para la manipulación DOM, manejo de eventos, multitarea preventiva, gráficos de lienzo, manipulación de cadenas JS nativas, etc.
Para obtener más información sobre cómo funciona Saste, consulte el informe de Haste, aunque tenga cuidado de que las partes de la prisa pueden haber cambiado bastante.
También debe echar un vistazo a la documentación y/o el código fuente para haste-lib , que reside en el directorio libraries/haste-lib , y los pequeños programas en el directorio examples , para comenzar.
Al escribir programas, probablemente desee usar un JavaScript nativo en su programa; Atagimientos a las bibliotecas nativas, por ejemplo. La forma preferida de hacer esto es la Haste.Foreign Módulo extranjero:
{-# LANGUAGE OverloadedStrings #-}
import Haste.Foreign
addTwo :: Int -> Int -> IO Int
addTwo = ffi "(function(x, y) {return x + y;})"
La función ffi es un poco más segura que la GHC FFI, ya que hace cumplir algún tipo de invariantes en los valores devueltos de JS, y es más conveniente. En cuanto al rendimiento, es aproximadamente tan rápido como el GHC FFI, excepto los tipos complejos (listas, registros, etc.) donde es un orden de magnitud más rápido.
Si no se siente cómodo tirando toda su base de código Legacy JavaScript, puede exportar funciones seleccionadas de su programa de prisa y llamarlas desde JavaScript:
diversión.hs:
{-# LANGUAGE OverloadedStrings #-}
import Haste.Foreign
import Haste.Prim (toJSStr)
fun :: Int -> String -> IO String
fun n s = return $ "The number is " ++ show n ++ " and the string is " ++ s
main = do
export "fun" fun
Legacy.js:
function mymain() {
console.log(Haste.fun(42, "hello"));
}
... luego compilar con:
$ hastec '--start=$HASTE_MAIN(); mymain();' --with-js=legacy.js fun.hs
fun.hs exportará la función fun cuando se ejecute su función main . Nuestro JavaScript obviamente necesita ejecutarse después de eso, por lo que creamos nuestra función principal "real" en legacy.js . Finalmente, le decimos al compilador que comience el programa ejecutando primero la función main de Haste ( $HASTE_MAIN se reemplaza por cualquier nombre que el compilador elija para el Precio main ) y luego ejecutando nuestro propio mymain .
La mecánica de Haste.Foreign se describe en detalle en este documento.
Usando el marco de la jerarquía de módulos Haste.App , puede escribir fácilmente aplicaciones web que se comuniquen con un servidor sin tener que escribir una sola línea de AJAX/WebSockets/lo que sea. Lo mejor de todo: es completamente seguro.
En esencia, escribe su aplicación web como un solo programa: no más separación forzada de su cliente y código de servidor. Luego compila su programa una vez que usa Haste y una vez usando GHC, y los dos compiladores generarán mágicamente el código del cliente y el servidor, respectivamente.
Deberá tener las mismas bibliotecas instaladas con Haste y Vanilla GHC (a menos que use la compilación condicional para evitar esto). haste-compiler viene incluido con toda la haste-lib , por lo que solo necesita preocuparse por esto si está utilizando bibliotecas de terceros. También necesitará un servidor web para servir sus archivos HTML y JS; El binario generado por el pase de compilación nativo solo se comunica con la parte del cliente usando WebSockets y no sirve ningún archivo por sí solo.
Ejemplos de Haste.App in Action están disponibles en examples/haste-app y examples/chatbox .
Para obtener más información sobre cómo funciona exactamente esto, consulte este documento.
Puede construir su propio conjunto de documentos para Saste-Lib ejecutando cabal haddock en el directorio base de prisa como con cualquier otro paquete.
O simplemente podría mirar los documentos en línea.
Haste puede usar las bibliotecas de Haskell estándar. Sin embargo, algunas operaciones primitivas aún no se implementan, lo que significa que cualquier código que haga uso de ellas le dará una advertencia del compilador, luego morirá en tiempo de ejecución con un error de enojo. Algunas bibliotecas también dependen del código C externo: si desea utilizar una biblioteca de este tipo, deberá portar los bits de C a JavaScript usted mismo (tal vez usando Emscripten) y vincularlos a su programa usando --with-js .
No se implementan todas las primopías GHC; Si se encuentra con una primopial no implementada, infórmelo junto con un pequeño caso de prueba que demuestre el problema.
La plantilla Haskell todavía está rota.
El código generado no es compatible con las ADVANCED_OPTIMIZATIONS del compilador de cierre de vainilla, ya que no está garantizado para preservar Function.length . haste-boot Bundle una versión parcheada de compatibilidad de cierre que preserva esta propiedad. Invocar hastec con la opción --opt-minify utilizará esta versión parcheada para minificar el código generado con optimizaciones avanzadas.