Haskell通过FFI与Ruby绑定?

时间:2021-08-20 16:50:56

Since both ruby and Haskell supports FFI,

由于ruby和Haskell都支持FFI,

  • Is it possible to call Haskell code from ruby, may be through FFI ?
  • 是否有可能从ruby调用Haskell代码,可能是通过FFI?

  • Is there any Haskell binding in Ruby ?
  • Ruby中有任何Haskell绑定吗?

6 个解决方案

#1


11  

I'm a bit late to this discussion, but I'm currently writing a bridge between Ruby and Haskell. It's at http://github.com/mwotton/Hubris - it's a binding that works at the C level. Still at a very early stage of development, though.

我讨论的时间有点晚,但我现在正在写Ruby和Haskell之间的桥梁。它位于http://github.com/mwotton/Hubris - 它是一个在C级别工作的绑定。尽管如此,仍处于发展的初期阶段。

#2


8  

GHC 6.12.1 supports building dynamic libraries on Linux. Try something like:

GHC 6.12.1支持在Linux上构建动态库。尝试以下方法:

Example.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

wrapper.c

#include <stdlib.h>

#include "HsFFI.h"

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

void
example_exit (void)
{
  hs_exit ();
}

script.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

Makefile

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

Commands to run

make
ruby script.rb

#3


6  

I haven't seen it done before, but it's possible.

我以前没见过它,但它有可能。

  • Use Haskell's FFI to wrap libruby. Your main executable will be written in Haskell, which will call ruby_init() and related functions, in order to run the Ruby interpreter in-process. This does allow you to run arbitrary Ruby code, though.
  • 使用Haskell的FFI来包装libruby。您的主要可执行文件将在Haskell中编写,它将调用ruby_init()和相关函数,以便在进程中运行Ruby解释器。但这确实允许您运行任意Ruby代码。

  • Use Ruby's FFI to wrap a GHC module as a library. Your Ruby script must call hs_init(), and can only access foreign exported functions.
  • 使用Ruby的FFI将GHC模块包装为库。您的Ruby脚本必须调用hs_init(),并且只能访问外部导出的函数。

You'll need to write glue code, some in C, to get either of those two options working.

您需要编写胶水代码,其中一些在C中,以获得这两个选项中的任何一个。

  • Run Ruby and Haskell in separate processes, using some IPC to communicate between them. Maybe XML-RPC (Haskell/Ruby), or JSON (Haskell/Ruby) over sockets, or maybe even just pipes with your own custom protocol.
  • 在单独的进程中运行Ruby和Haskell,使用一些IPC在它们之间进行通信。也许XML-RPC(Haskell / Ruby),或JSON(Haskell / Ruby)通过套接字,或者甚至只是管道与您自己的自定义协议。

I don't know what your requirements are, but this is what I'd go for -- it's a lot easier.

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

#4


1  

I am not sure about the Haskell side, but here is a cool video from Mountain West Ruby Conf 09 about working with FFI from Ruby. It looks like a pretty nice interface.

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

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

#5


0  

@ephemient, I am actually looking for someways to use Ruby (high level + dynamic) to be the main controller logic and invoking haskell for large amount of data crunching (functional + speed)

@ephemient,我实际上正在寻找一些使用Ruby(高级+动态)作为主控制器逻辑并调用haskell进行大量数据处理(功能+速度)

I think native binding is close to non-existence, apart from this tweet http://twitter.com/BlurredWeasel/status/1321484127

除了这条推文之外,我认为原生绑定接近于不存在http://twitter.com/BlurredWeasel/status/1321484127

Using JSON RPC will be probably the easiest way to implement where there is a thin wrapper in ruby to (method_missing) to invoke haskell over JSON/Socket.

使用JSON RPC可能是实现最简单的方法,在ruby中有一个瘦包装器(method_missing)来通过JSON / Socket调用haskell。

JSON has the advantage of being able to easily map primitives to native types between various languages..

JSON的优点是能够在各种语言之间轻松地将基元映射到本机类型。

class SciHs
  def method_missing(method, *args) 
     // json encode
     // request Haskell over tcp socket or unix pipes
     // json decode
  end
end 

Other alternative for fast number crunching in ruby (+ functional style)

其他替代红宝石快速数字运算(+功能样式)

  • NArray or other scientific library in ruby
  • NArray或红宝石中的其他科学图书馆

  • Ruby binding of GNU Scientific Library
  • GNU科学图书馆的Ruby绑定

  • or go ruby 1.9 and use YARV2LLVM to JIT the calculation logic into LLVM for faster execution.
  • 或者使用ruby 1.9并使用YARV2LLVM将计算逻辑JIT到LLVM中以加快执行速度。

Thoughts anyone?

#6


0  

I tried exactly this (I'm the one from the mentioned tweet).

我试过这个(我是上述推文中的那个)。

I didn't think of the libruby approach, but I spent a fair amount trying to use ruby's FFI to wrap an exported function from haskell, and could never quite get it to all link and run.

我没有想到libruby的方法,但我花了相当多的钱试图使用ruby的FFI从haskell包装导出的函数,并且永远无法完全将它传到所有链接并运行。

If you look at haskell's FFI examples, you'll see that they all include a C main() function. Since ruby's FFI doesn't have (and can't have) a main(), that won't work. If you try without that, you end up with weird link errors.

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

I can share what I have with you, ping me on freenode (cschneid), or on twitter (BlurredWeasel).

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

#1


11  

I'm a bit late to this discussion, but I'm currently writing a bridge between Ruby and Haskell. It's at http://github.com/mwotton/Hubris - it's a binding that works at the C level. Still at a very early stage of development, though.

我讨论的时间有点晚,但我现在正在写Ruby和Haskell之间的桥梁。它位于http://github.com/mwotton/Hubris - 它是一个在C级别工作的绑定。尽管如此,仍处于发展的初期阶段。

#2


8  

GHC 6.12.1 supports building dynamic libraries on Linux. Try something like:

GHC 6.12.1支持在Linux上构建动态库。尝试以下方法:

Example.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

wrapper.c

#include <stdlib.h>

#include "HsFFI.h"

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

void
example_exit (void)
{
  hs_exit ();
}

script.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

Makefile

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

Commands to run

make
ruby script.rb

#3


6  

I haven't seen it done before, but it's possible.

我以前没见过它,但它有可能。

  • Use Haskell's FFI to wrap libruby. Your main executable will be written in Haskell, which will call ruby_init() and related functions, in order to run the Ruby interpreter in-process. This does allow you to run arbitrary Ruby code, though.
  • 使用Haskell的FFI来包装libruby。您的主要可执行文件将在Haskell中编写,它将调用ruby_init()和相关函数,以便在进程中运行Ruby解释器。但这确实允许您运行任意Ruby代码。

  • Use Ruby's FFI to wrap a GHC module as a library. Your Ruby script must call hs_init(), and can only access foreign exported functions.
  • 使用Ruby的FFI将GHC模块包装为库。您的Ruby脚本必须调用hs_init(),并且只能访问外部导出的函数。

You'll need to write glue code, some in C, to get either of those two options working.

您需要编写胶水代码,其中一些在C中,以获得这两个选项中的任何一个。

  • Run Ruby and Haskell in separate processes, using some IPC to communicate between them. Maybe XML-RPC (Haskell/Ruby), or JSON (Haskell/Ruby) over sockets, or maybe even just pipes with your own custom protocol.
  • 在单独的进程中运行Ruby和Haskell,使用一些IPC在它们之间进行通信。也许XML-RPC(Haskell / Ruby),或JSON(Haskell / Ruby)通过套接字,或者甚至只是管道与您自己的自定义协议。

I don't know what your requirements are, but this is what I'd go for -- it's a lot easier.

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

#4


1  

I am not sure about the Haskell side, but here is a cool video from Mountain West Ruby Conf 09 about working with FFI from Ruby. It looks like a pretty nice interface.

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

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

#5


0  

@ephemient, I am actually looking for someways to use Ruby (high level + dynamic) to be the main controller logic and invoking haskell for large amount of data crunching (functional + speed)

@ephemient,我实际上正在寻找一些使用Ruby(高级+动态)作为主控制器逻辑并调用haskell进行大量数据处理(功能+速度)

I think native binding is close to non-existence, apart from this tweet http://twitter.com/BlurredWeasel/status/1321484127

除了这条推文之外,我认为原生绑定接近于不存在http://twitter.com/BlurredWeasel/status/1321484127

Using JSON RPC will be probably the easiest way to implement where there is a thin wrapper in ruby to (method_missing) to invoke haskell over JSON/Socket.

使用JSON RPC可能是实现最简单的方法,在ruby中有一个瘦包装器(method_missing)来通过JSON / Socket调用haskell。

JSON has the advantage of being able to easily map primitives to native types between various languages..

JSON的优点是能够在各种语言之间轻松地将基元映射到本机类型。

class SciHs
  def method_missing(method, *args) 
     // json encode
     // request Haskell over tcp socket or unix pipes
     // json decode
  end
end 

Other alternative for fast number crunching in ruby (+ functional style)

其他替代红宝石快速数字运算(+功能样式)

  • NArray or other scientific library in ruby
  • NArray或红宝石中的其他科学图书馆

  • Ruby binding of GNU Scientific Library
  • GNU科学图书馆的Ruby绑定

  • or go ruby 1.9 and use YARV2LLVM to JIT the calculation logic into LLVM for faster execution.
  • 或者使用ruby 1.9并使用YARV2LLVM将计算逻辑JIT到LLVM中以加快执行速度。

Thoughts anyone?

#6


0  

I tried exactly this (I'm the one from the mentioned tweet).

我试过这个(我是上述推文中的那个)。

I didn't think of the libruby approach, but I spent a fair amount trying to use ruby's FFI to wrap an exported function from haskell, and could never quite get it to all link and run.

我没有想到libruby的方法,但我花了相当多的钱试图使用ruby的FFI从haskell包装导出的函数,并且永远无法完全将它传到所有链接并运行。

If you look at haskell's FFI examples, you'll see that they all include a C main() function. Since ruby's FFI doesn't have (and can't have) a main(), that won't work. If you try without that, you end up with weird link errors.

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

I can share what I have with you, ping me on freenode (cschneid), or on twitter (BlurredWeasel).

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