从Haskell生成JavaScript代码的编译器。
它甚至有一个网站和一个邮件列表。
您有三个匆忙的选择:从骇客,github或一种预先构建的二进制软件包之一安装。在前两种情况下,如果尚未这样做,则需要添加添加Cabal的bin目录,通常~/.cabal/bin $PATH从Mac,Portable Windows或Generic Linux软件包安装时,您可能需要在$PATH中添加path/to/haste-compiler/bin 。 Debian软件包以及Windows安装程序和通用Linux软件包中包含的可选安装脚本会自动处理此功能。
或者,您可以从Hackage安装最新的稳定版本:
$ cabal install haste-compiler
$ haste-boot
从github源建造同样容易。检查源后, cd到源树并运行:
$ cabal install
$ haste-boot --force --local
另外,您也可以使用stack从github源构建:
$ stack install
$ haste-boot --force --local
有关各种平台的构建要求和程序的更多信息,请参见doc/building.md 。
如果您在haste-boot安装的haste-cabal Haste-Coot)上遇到问题,则可以尝试从头开始构建它,然后将其传递--no-haste-cabal国旗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
从Github急速安装时,您可能应该先运行测试套件,以验证所有内容是否有效。为此,在急速根目录中执行./runtests.sh 。您也可以通过执行./runtests.sh NameOfTest来运行特定的测试。默认情况下,测试套件使用nodejs解释器,但是可以通过设置JS环境变量进行修改: JS=other-js-interpreter ./runtests.sh 。其他JavaScript口译员可能会或可能行不通。 runtests.sh从hackage安装时未下载。您必须从Github下载它。
要构建使用--opt-minify编译时使用的修补闭合编译器,请获取闭合源,应用patches/closure-argument-removal.patch并像往常一样构建它。但是,这通常不是必需的,因为haste-boot在运行时会获取预编译的闭合二进制。
有关更详细的构建说明,请参见doc/building.md 。
HASTE已经过测试以在Windows和OSX平台上工作,但主要是在GNU/Linux上开发的。因此,在GNU/Linux平台上运行可能会使您更少的错误。
将您的Haskell程序编译到准备中的JavaScript Blob中,准备包含在HTML文档中或使用命令行解释器运行:
$ hastec myprog.hs
这等同于调用GHC -make myprog.hs; JS BLOB完成加载后,Main.main将立即被召唤。
您可以将相同的旗帜传递给HASTEC,就像您通常传递给GHC:
$ hastec -O2 -fglasgow-exts myprog.hs
Haste还拥有自己的一组命令行参数。用它来调用--help来阅读有关它们的更多信息。特别是--opt-all , --opt-minify , --start和--with-js应该相当有趣。
如果您希望包装与Haste和GHC一起编译,则可能需要使用CPP扩展程序进行有条件的编译。急速在其编译的所有模块中定义了预处理器符号__HASTE__ 。该符号也可以用来区分急速版本,因为它被定义为当前急速版本的整数表示。它的格式为MAJOR*10 000 + MINOR*100 + MICRO 。因此,1.2.3版将表示为10203,为0.4.3为403。
Haste还配备了Cabal和GHC-PKG的包装纸,分别名为Haste-Cabal和Haste-Pkg。您可以像使用Vanilla GHC和Cabal一样使用它们来安装包裹:
$ haste-cabal install mtl
最后,您可以使用Haste.Foreign模块在捆绑的haste-lib库中与JavaScript代码进行交互。有关此信息的更多信息,请参见doc/js-externals.txt 。该库还包含各种功能,用于DOM操纵,事件处理,先发制人多任务处理,帆布图形,本机JS字符串操纵等。
有关急速工作的更多信息,请参阅急速报告,尽管要当心急速的部分可能发生了很大变化。
您还应该查看位于libraries/haste-lib目录中的haste-lib文档和/或源代码,以及examples目录中的小程序。
编写程序时,您可能需要在程序中使用一些本机JavaScript;例如,与本地库的绑定。这样做的首选方法是Haste.Foreign外国模块:
{-# LANGUAGE OverloadedStrings #-}
import Haste.Foreign
addTwo :: Int -> Int -> IO Int
addTwo = ffi "(function(x, y) {return x + y;})"
ffi函数比GHC FFI更安全,因为它在从JS返回的值上执行某种类型的不变性,并且更方便。从性能角度来看,它大致与GHC FFI的速度大致一样快,除了复杂类型(列表,记录等),它是一个数量级的顺序。
如果您不愿意丢弃整个旧的JavaScript代码库,则可以从急速程序中导出选定的功能,并从JavaScript致电:
fun.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"));
}
...然后编译:
$ hastec '--start=$HASTE_MAIN(); mymain();' --with-js=legacy.js fun.hs
当运行其main函数时, fun.hs将导出功能fun 。我们的JavaScript显然需要在此之后运行,因此我们在legacy.js中创建了“真实”的主要功能。最后,我们告诉编译器首先执行Haste的main功能( $HASTE_MAIN将被编译器选择为Haste main选择的任何名称所取代),然后执行我们自己的mymain 。
本文详细介绍了Haste.Foreign的机制。
使用Haste.App模块层次结构中的框架,您可以轻松编写与服务器通信的Web应用程序,而无需编写AJAX/Websockets/whitch的单行。最重要的是:它完全是安全的。
从本质上讲,您将Web应用程序写为一个程序 - 不再有强制分离客户端和服务器代码。然后,您一旦使用急速进行编译,然后使用GHC来编译程序,两个编译器将分别神奇地生成客户端和服务器代码。
您将需要与Haste和Vanilla GHC同时安装相同的库(除非您使用条件汇编来解决此问题)。 haste-compiler捆绑在一起,所有haste-lib都捆绑在一起,因此,如果您使用第三方图书馆,您只需要担心这一点。您还需要一个Web服务器,以服务您的HTML和JS文件;本机汇编通行证生成的二进制文件仅使用Websocket与客户部件进行通信,并且不会单独使用任何文件。
haste.app in Action的示例可以在examples/haste-app和examples/chatbox中获得。
有关此操作方式的更多信息,请参见本文。
您可以与其他任何包装一样,在急速基本目录中运行cabal haddock为急速lib构建自己的文档。
或者,您可以查看在线文档。
Haste能够使用标准的Haskell库。但是,某些原始操作仍未实施,这意味着任何使用它们的代码都会给您发出编译器警告,然后在运行时死亡,并以愤怒的错误。一些库还取决于外部C代码 - 如果您想使用此类库,则需要将C位移植到JavaScript自己(也许使用Emscripten),并使用--with-js将它们链接到您的程序中。
并非所有GHC序列都已实施;如果您遇到未完成的PRIMOP,请与一个小的测试用例一起报告,以证明问题。
模板Haskell仍然破裂。
生成的代码与香草闭合编译器的ADVANCED_OPTIMIZATIONS不兼容,因为它不能保证保留Function.length 。 haste-boot捆绑了兼容性的封闭式修补版本,该版本确实保留了此属性。使用--opt-minify选项调用hastec将使用此修补版本来缩小具有高级优化的生成代码。