bar*_*oap 18
如果您可以使用Python代码调用C,则可以调用已通过FFI导出的Haskell函数
另一种方法是编写一个标准的IPC接口,在darcs和pandoc的情况下只是将它们称为vanilla可执行文件,解析它们的输出可能就是这样.
至于在Haskell端自动生成无聊,重复,FFI和编组代码,我建议使用c2hs,它允许你基于现有的C接口自动生成很多东西.python可能有类似的东西.
据我所知,SWIG从来没有为Haskell实现,大概是因为它迎合了不那么严格类型的语言.
一个额外的想法:效率低于直接C绑定,但比向Haskell外壳更高效的是一个rpc系统,如Apache Thrift:http://incubator.apache.org/thrift/
我发现节俭易于使用,支持良好且性能合理.一旦你的Haskell服务器运行,本地通信的成本相当便宜,虽然你在编组/解组中支付的费用比直接使用c类型多一点.
还有至少两个用于从Haskell调用Python的包,missingpy(http://hackage.haskell.org/package/MissingPy)和cpython(http://hackage.haskell.org/package/cpython).后者声称计划在另一个方向提供支持 - 尽管你必须询问作者是否仍然如此,如果是这样的话.
另一种选择是连字符,可以在这里找到.基本用法如下所示:
>>> 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]
Run Code Online (Sandbox Code Playgroud)
这似乎是一个不如其他答案中的其他选项轻量级的解决方案.
作为额外重量的回报,您似乎可以从Haskell到Python获得完整的桥梁.然而HaPy
,github.com/nh2/call-haskell-from-anything
只允许你使用Python中的Haskell函数,如果Haskell函数的所有参数都来自相当基本的类型并返回一个相当基本的类型,hyphen
似乎让你使用任意函数.它可以做到这一点,因为它向python引入了一个表示Haskell堆上任意对象的类型.
这些从python查看的'haskell对象'作为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]
Run Code Online (Sandbox Code Playgroud)
有关更多示例,请参阅自述文件!
它似乎也处理各种奇特的事情,比如在Haskell和Python之间转换异常.
菜鸟在这里。
但是我确实设法使用Haskell的FFI从python调用了用户定义的Haskell函数。基本上,我将Haskell函数编译为一个dll,并使用python中的ctypes导入了该dll。因此该功能在python中可用。
我在这里编写了程序:https : //justa0xc0de.wordpress.com/2015/01/08/using_haskell_function_in_python/
希望这可以帮助。
有一个包装器允许在这里从Python调用Haskell函数:
https://github.com/sakana/HaPy
从粗略的检查来看,似乎要求Haskell函数具有相对简单的类型签名(基本上,所涉及的所有类型最好是像int知道的Int和Float,或者这种形式的事物列表,或列表列表,等等).
提供了一个示例,其中一个具有此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
Run Code Online (Sandbox Code Playgroud)
一个人像这样访问它:
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")
Run Code Online (Sandbox Code Playgroud)
不幸的是,你需要在Haskell端做一些导出管道.