Вызов функций Haskell из Python

Я хочу использовать некоторые библиотеки Haskell (например, Darcs, Pandoc) из Python, но, похоже, в Python нет прямого интерфейса сторонних функций для Haskell. Есть ли способ сделать это?


person minhee    schedule 16.02.2011    source источник


Ответы (6)


Если вы можете заставить свой код Python вызывать C, вы можете вызывать функции Haskell, которые были экспортированы через FFI

Другим подходом может быть написание стандартного интерфейса IPC, в случае с darcs и pandoc просто вызов их как исполняемых файлов vanilla и анализ их вывода может быть способом.

Что касается автоматизации генерации скучного, повторяющегося кода FFI и маршаллинга на стороне Haskell, я бы рекомендовал c2hs, который позволяет вам автоматически генерировать много на основе существующего интерфейса C. Там, вероятно, аналогичные вещи для python.

Увы, SWIG, насколько мне известно, никогда не был реализован для Haskell, по-видимому, потому, что он обслуживает менее строго типизированные языки.

person barsoap    schedule 16.02.2011
comment
вот еще немного расширения подхода ffi: wiki.python.org/moin/PythonVsHaskell - person sclv; 16.02.2011

Еще одна идея: чем-то менее эффективным, чем прямое связывание C, но более эффективным, чем переход к Haskell, является система rpc, такая как Apache Thrift: http://incubator.apache.org/thrift/

Я обнаружил, что бережливость проста в использовании, хорошо поддерживается и достаточно эффективна. Когда у вас запущен сервер Haskell, стоимость локальной связи становится довольно низкой, хотя вы платите немного больше за маршалинг/демаршаллинг, чем за прямое использование типов c.

Также есть по крайней мере два пакета для вызова Python из Haskell, Missingpy (http://hackage.haskell.org/package/MissingPy) и cpython (http://hackage.haskell.org/package/cpython). Последний утверждает, что планируется поддержка в другом направлении - хотя вам придется спросить автора, так ли это до сих пор, и если да, то когда.

person sclv    schedule 16.02.2011
comment
@sciv Нашли ли вы примеры вызова сторонних функций в Apache Thrift? Я столкнулся с той же проблемой здесь. - person Anderson Green; 14.10.2012
comment
что ты имеешь в виду ффи? thrift — это сериализация и клиент-серверная библиотека. - person sclv; 17.10.2012

Другой вариант — дефис, который можно найти здесь. Базовое использование выглядит примерно так:

>>> import hyphen, hs.Prelude
>>> hs.Prelude.sum([1,2,3]) # list converted to Haskell list
6
>>> hs.Prelude.drop(5, "Hello, world")
", world"
>>> hs.Prelude.drop(1, [1,2,3])
<hs.GHC.Types.[] object of Haskell type [GHC.Integer.Integer], containing '[2,3]'>
>>> list(hs.Prelude.drop(1, [1,2,3]))   # Convert back to Python list
[2, 3]

Это кажется менее легким решением, чем некоторые другие варианты в других ответах.

В обмен на дополнительный вес вы, кажется, получаете полный мост от Haskell к Python. В то время как HaPy и github.com/nh2/call-haskell-from-anything позволяют вам использовать функцию Haskell из Python только в том случае, если эта функция Haskell имеет все свои аргументы из довольно простых типов и возвращает довольно простой тип, hyphen, похоже, позволяет вам использовать произвольные функции. Он может это сделать, потому что вводит в python тип, представляющий произвольный объект в куче Haskell.

Эти «объекты haskell, просматриваемые из python», ведут себя довольно хорошо как объекты python. Например, Haskell Map ведет себя немного как словари:

>>> import hs.Data.Map
>>> my_map = hs.Data.Map.fromList([(1, 'Hello'), (2, 'World')])
>>> my_map[1]
'Hello'
>>> print(sorted([key for key in my_map]))
[1, 2]

См. readme для многих других примеров!

Он также, кажется, обрабатывает различные причудливые вещи, такие как преобразование исключений между Haskell и Python.

person circular-ruin    schedule 07.11.2015

Нуб здесь.

Но мне удалось вызвать пользовательские функции Haskell из python, используя Haskell FFI. В основном я скомпилировал функцию Haskell в dll и импортировал dll, используя ctypes в python. Так функция стала доступна в питоне.

Я написал процедуру здесь: https://justa0xc0de.wordpress.com/2015/01/08/using_haskell_function_in_python/

Надеюсь это поможет.

person Minar Ashiq Tishan    schedule 11.01.2015
comment
Это выглядит как довольно полезная запись, но вы должны извлечь некоторые ключевые идеи и скопировать их в свой ответ. В противном случае он рискует быть удаленным только как ссылка. - person dfeuer; 11.01.2015

Здесь есть оболочка, которая позволяет вызывать функции Haskell из Python:

https://github.com/sakana/HaPy

При беглом осмотре кажется, что требуется, чтобы функции Haskell имели относительно простые сигнатуры типов (в основном, все задействованные типы должны быть такими, как Int и Float, о которых c знает, или списками элементов этой формы, или списками списков). , или так далее).

Приведен пример, где есть этот код Haskell:

module ExampleModule where

import Data.Char

foo :: Double -> Double -> Double
foo = (*)

bar :: Int -> Int
bar i = sum [1..i]

baz :: Int -> Bool
baz = (> 5)

arr_arg :: [Int] -> Int
arr_arg = sum

arr_ret :: Int -> [Int]
arr_ret i = [1..i]

arr_complex :: [[Int]] -> [[Int]]
arr_complex = map (map (* 2))

string_fun :: String -> String
string_fun str = str ++ reverse str

char_test :: Char -> Int
char_test = ord

и один обращается к нему следующим образом:

from HaPy import ExampleModule

print "3 * 7 is", ExampleModule.foo(3,7)
print "sum from 1 to 10 is", ExampleModule.bar(10)
print "3 > 5 is", ExampleModule.baz(3)

print "sum from 1 to 100 is", ExampleModule.arr_arg(range(101))
print "numbers from 1 to 10 are", ExampleModule.arr_ret(10)

print "complex array passing:", ExampleModule.arr_complex([range(3), [], range(100)])
print "string fun:", ExampleModule.string_fun("This isn't really a palindrome.")

s = ExampleModule.string_fun("abc\000def")
print "string fun with nulls:", s,
for c in s:
    print ord(c),
print

print "char test:", ExampleModule.char_test("t")

К сожалению, вам нужно сделать некоторую экспортную сантехнику на стороне Haskell.

person circular-ruin    schedule 13.10.2015

По крайней мере, для pandoc вы можете использовать эти привязки C: https://github.com/toyvo/libpandoc

person John MacFarlane    schedule 16.02.2011
comment
Спасибо! Ваш ответ очень полезен для меня. - person minhee; 17.02.2011