7

rubyもHaskellもFFIに対応しているので、

  • Ruby から Haskell コードを呼び出すことは可能ですか?
  • Ruby に Haskell バインディングはありますか?
4

6 に答える 6

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

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

メイクファイル

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ます。ruby_init()Ruby インタープリターをインプロセスで実行するために、メインの実行可能ファイルは Haskell で記述され、関連する関数が呼び出されます。ただし、これにより、任意の Ruby コードを実行できます。
  • Ruby の FFI を使用して GHC モジュールをライブラリとしてラップします。Ruby スクリプトは を呼び出す必要があり、 ed 関数hs_init()にのみアクセスできます。foreign export

これら 2 つのオプションのいずれかを機能させるには、グルー コード (一部は C) を記述する必要があります。

  • IPC を使用して Ruby と Haskell を別々のプロセスで実行し、それらの間で通信します。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 

ルビーでの高速数値計算のその他の代替手段(+機能スタイル)

  • NArrayまたはルビーの他の科学図書館
  • GNUScientificLibraryのRubyバインディング
  • または、ruby 1.9に移行し、 YARV2LLVMを使用して計算ロジックをLLVMにJITして、実行を高速化します。

誰か考えますか?

于 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 に答える