Связывание Haskell с Ruby через FFI? - PullRequest
7 голосов
/ 24 марта 2009

Поскольку как ruby, так и Haskell поддерживают FFI,

  • Можно ли вызвать код на Haskell из ruby, может через FFI?
  • Есть ли в Ruby привязка Haskell?

Ответы [ 6 ]

11 голосов
/ 14 сентября 2009

Я немного опоздал к этому обсуждению, но в настоящее время я пишу мост между Руби и Хаскеллом. Это на http://github.com/mwotton/Hubris - это привязка, которая работает на уровне C. Тем не менее, все еще на очень ранней стадии развития.

8 голосов
/ 12 марта 2010

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

Команды для запуска

make
ruby script.rb
6 голосов
/ 24 марта 2009

Я не видел, чтобы это было сделано раньше, но это возможно.

  • Используйте FFI Haskell, чтобы обернуть libruby. Ваш основной исполняемый файл будет написан на Haskell, который будет вызывать ruby_init() и связанные с ним функции, чтобы запустить интерпретатор Ruby в процессе. Это позволяет вам запускать произвольный код на Ruby.
  • Используйте FFI Руби, чтобы обернуть модуль GHC как библиотеку . Ваш скрипт на Ruby должен вызывать hs_init() и иметь доступ только к foreign export функциям ed.

Вам нужно написать склеенный код, некоторые на C, чтобы заставить работать любой из этих двух вариантов.

  • Запускать Ruby и Haskell в отдельных процессах, используя некоторый IPC для связи между ними. Может быть XML-RPC ( Haskell / Ruby ) или JSON ( Haskell / Ruby ) поверх сокетов, или, может быть, даже просто каналы с ваш собственный протокол.

Я не знаю, каковы ваши требования, но я бы на это пошел - намного проще.

1 голос
/ 26 марта 2009

Я не уверен насчет стороны Haskell, но вот классное видео от Mountain West Ruby Conf 09 о работе с FFI из Ruby. Это выглядит как довольно приятный интерфейс.

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

0 голосов
/ 26 марта 2009

Я попробовал именно это (я один из упомянутого твита).

Я не думал о подходе libruby, но потратил немало сил, пытаясь использовать FFI для ruby, чтобы обернуть экспортированную функцию из haskell, и так и не смог получить ее по всей ссылке и запустить.

Если вы посмотрите на примеры FFI в haskell, то увидите, что все они включают функцию C main (). Так как FFI в ruby ​​не имеет (и не может иметь) main (), это не сработает. Если вы попробуете без этого, вы получите странные ошибки ссылок.

Я могу поделиться с вами тем, что у меня есть, пинговать меня по freenode (cschneid) или по твиттеру (BlurredWeasel).

0 голосов
/ 26 марта 2009

@ ephemient, на самом деле я ищу способы использовать Ruby (высокий уровень + динамический) в качестве логики основного контроллера и вызывать haskell для большого перебора данных (функционал + скорость)

Я думаю, что нативное связывание близко к несуществованию, кроме этого твита http://twitter.com/BlurredWeasel/status/1321484127

Использование JSON RPC будет, пожалуй, самым простым способом реализации, когда в ruby ​​существует тонкая оболочка для (method_missing) для вызова haskell через JSON / Socket.

Преимущество JSON заключается в возможности простого сопоставления примитивов с нативными типами между различными языками.

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

Другая альтернатива для быстрого перебора чисел в рубине (+ функциональный стиль)

  • NArray или другая научная библиотека в ruby ​​
  • Рубиновый переплет научной библиотеки GNU
  • или перейдите на ruby ​​1.9 и используйте YARV2LLVM для перевода логики вычисления в LLVM для более быстрого выполнения.

Кто-нибудь думает?

...