由于Ruby和Haskell都支持FFI,
- 是否有可能通过FFI从Ruby调用Haskell代码?
- 在Ruby中是否有任何Haskell绑定?
我有点晚来参加这个讨论,但目前我正在编写一个Ruby和Haskell之间的桥接器。它在http://github.com/mwotton/Hubris上 - 这是一个在C层面工作的绑定。虽然还处于早期开发阶段。
GHC 6.12.1支持在Linux上构建动态库。尝试类似以下命令:
{-# LANGUAGE ForeignFunctionInterface #-}
module Example where
import Foreign.C.Types
fibonacci :: Int -> Int
fibonacci n = fibs !! n
where fibs = 0 : 1 : zipWith (+) fibs (tail fibs)
fibonacci_hs :: CInt -> CInt
fibonacci_hs = fromIntegral . fibonacci . fromIntegral
foreign export ccall fibonacci_hs :: CInt -> CInt
#include <stdlib.h>
#include "HsFFI.h"
void
example_init (void)
{
hs_init (NULL, NULL);
}
void
example_exit (void)
{
hs_exit ();
}
require 'dl'
require 'dl/import'
module Example
extend DL::Importable
dlload "./libffi-example.so"
extern "void example_init()"
extern "void example_exit()"
extern "int fibonacci_hs(int)"
end
Example.example_init
1.upto( 40 ) do | x |
puts "#{ x } -> #{ Example.fibonacci_hs x }\n"
end
Example.example_exit
GHC=ghc-6.12.1
libffi-example.so: Example.o wrapper.o Example_stub.o
$(GHC) -o $@ -shared -dynamic -fPIC $^ -lHSrts-ghc6.12.1
Example_stub.c Example_stub.h Example.o: Example.hs
$(GHC) -c -dynamic -fPIC Example.hs
Example_stub.o: Example_stub.c
$(GHC) -c -dynamic -fPIC Example_stub.c
wrapper.o: wrapper.c Example_stub.h
$(GHC) -c -dynamic -fPIC wrapper.c
clean:
rm -f *.hi *.o *_stub.[ch] *.so
make
ruby script.rb
我之前没有见过这样的做法,但是这是可能的。
libruby
。您的主要可执行文件将由 Haskell 编写,它将调用 ruby_init()
和相关函数以在进程内运行 Ruby 解释器。这确实允许您运行任意的 Ruby 代码。hs_init()
,并且只能访问 foreign export
函数。您需要编写一些粘合代码,其中一些是 C 语言,以使这两个选项中的任何一个都能正常工作。
我不知道您的要求是什么,但这是我会选择的方式——它要容易得多。
我不确定Haskell方面的情况,但这里有一个很酷的视频来自Mountain West Ruby Conf 09,讲述如何在Ruby中使用FFI。看起来是一个相当不错的接口。
http://mwrc2009.confreaks.com/13-mar-2009-16-10-ffi-jeremy-hinegardner.html
@ephemient,我正在寻找一些使用Ruby(高级+动态)作为主控制逻辑并调用Haskell进行大量数据处理(功能+速度)的方法。
我认为本地绑定接近不存在,除了这条推文http://twitter.com/BlurredWeasel/status/1321484127
使用JSON RPC可能是实现最简单的方法,在Ruby中有一个薄包装器(method_missing),可以通过JSON / Socket调用Haskell。
JSON具有将基元轻松映射到各种语言之间的本机类型的优点。
class SciHs
def method_missing(method, *args)
// json encode
// request Haskell over tcp socket or unix pipes
// json decode
end
end
在 Ruby 中进行快速数字计算的其他替代方案(+ 函数式风格)
有什么想法吗?
我尝试过这个方法(我就是那个在提到的推文中的人)。
我没有想到使用libruby的方法,但我花了相当多的时间尝试使用Ruby的FFI来包装从Haskell导出的函数,但始终无法完全链接和运行。
如果您查看Haskell的FFI示例,您会发现它们都包括一个C main()函数。由于Ruby的FFI没有(也不能有)main()函数,因此这种方法行不通。如果您尝试不使用它,您最终会遇到奇怪的链接错误。
我可以与您分享我的经验,请在freenode(cschneid)或Twitter(BlurredWeasel)上联系我。