7

由于 ruby​​ 和 Haskell 都支持 FFI,

  • 是否可以通过 FFI 从 ruby​​ 调用 Haskell 代码?
  • Ruby 中是否有任何 Haskell 绑定?
4

6 回答 6

11

我对这个讨论有点晚了,但我目前正在编写 Ruby 和 Haskell 之间的桥梁。它位于http://github.com/mwotton/Hubris - 它是一个在 C 级别工作的绑定。不过,仍处于非常早期的发展阶段。

于 2009-09-14T05:45:57.310 回答
8

GHC 6.12.1 支持在 Linux 上构建动态库。尝试类似:

例子.hs

{-# 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

包装器.c

#include <stdlib.h>

#include "HsFFI.h"

void
example_init (void)
{
  hs_init (NULL, NULL);
}

void
example_exit (void)
{
  hs_exit ();
}

脚本.rb

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
于 2010-03-12T02:56:45.717 回答
6

我以前没见过,但这是可能的。

  • 使用 Haskell 的 FFI 来包装libruby. 您的主要可执行文件将用 Haskell 编写,它将调用ruby_init()和相关函数,以便在进程内运行 Ruby 解释器。不过,这确实允许您运行任意 Ruby 代码。
  • 使用 Ruby 的 FFI 将 GHC 模块包装为库。您的 Ruby 脚本必须调用hs_init(),并且只能访问foreign exported 函数。

您需要编写胶水代码,其中一些是用 C 语言编写的,以使这两个选项中的任何一个都能正常工作。

  • 在不同的进程中运行 Ruby 和 Haskell,使用一些 IPC 在它们之间进行通信。也许 XML-RPC ( Haskell / Ruby ) 或 JSON ( Haskell / Ruby ) 通过套接字,或者甚至可能只是使用您自己的自定义协议的管道。

我不知道你的要求是什么,但这就是我想要的——它更容易。

于 2009-03-24T16:20:48.760 回答
1

我不确定 Haskell 方面,但这里有一段来自 Mountain West Ruby Conf 09 的关于使用 Ruby 的 FFI 的很酷的视频。它看起来像一个非常漂亮的界面。

http://mwrc2009.confreaks.com/13-mar-2009-16-10-ffi-jeremy-hinegardner.html

于 2009-03-26T07:21:11.927 回答
0

@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 中快速数字运算的其他替代方案(+ 功能风格)

  • ruby 中的 NArray 或其他科学库
  • GNU 科学库的 Ruby 绑定
  • 或者转到 ruby​​ 1.9 并使用YARV2LLVM将计算逻辑 JIT 到 LLVM 中以更快地执行。

有人想吗?

于 2009-03-26T06:22:38.400 回答
0

我完全尝试过这个(我是提到的推文中的那个)。

我没有想到 libruby 方法,但我花了相当多的时间尝试使用 ruby​​ 的 FFI 来包装从 haskell 导出的函数,并且永远无法将其完全连接到所有链接并运行。

如果您查看 haskell 的 FFI 示例,您会发现它们都包含一个 C main() 函数。由于 ruby​​ 的 FFI 没有(也不能有)main(),所以这行不通。如果你不这样做,你最终会出现奇怪的链接错误。

我可以与你分享我拥有的东西,在 freenode (cschneid) 或 twitter (BlurredWeasel) 上联系我。

于 2009-03-26T12:31:06.737 回答