我想从Python中使用一些Haskell库(例如Darcs,Pandoc),但是似乎Python没有直接与Haskell进行外部函数接口的方法。有没有什么办法可以实现这个功能呢?
另一个选项是连字号,可以在这里找到。基本用法看起来像这样:
>>> 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堆上任意对象的类型。
这些“从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]
请查看自述文件获取更多示例!
它似乎还可以处理各种花哨的事情,如在Haskell和Python之间转换异常。
另外一个想法:比直接绑定C但比通过外壳调用Haskell更高效的是rpc系统,例如Apache Thrift:http://incubator.apache.org/thrift/
我发现thrift易于使用、得到良好支持并具有合理的性能。一旦你运行了Haskell服务器,本地通信的成本相当便宜,尽管与直接使用c类型相比,在编组/解组方面付出了更高的代价。
还有至少两个用于从Haskell调用Python的包,missingpy(http://hackage.haskell.org/package/MissingPy)和cpython(http://hackage.haskell.org/package/cpython)。后者声称正在计划支持反向调用--尽管您必须询问作者,是否仍然是这种情况,如果是,何时可用。
我是一名新手。
但是,我成功地使用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和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端进行一些导出管道工作。