Haskell库的Python接口

问题描述

我想拥有一个Haskell库的Python接口。该库使用非标准/用户制作的类型,因此它们不能绑定到C类型-因此,我不确定FFI是否可以工作。

到目前为止,我的尝试包括将GHCI作为子进程运行,然后将代码作为输入传递并解析输出

# my current setup
from subprocess import Popen,PIPE,STDOUT
proc = Popen(["ghci","some_haskel_file.hs"],stdin=PIPE,stdout=PIPE,stderr=STDOUT)

# clear initial output of GHCI
for _ in range(7): proc.stdout.readline()

# this next part may be repeated multiple times
proc.stdin.write(some_haskell_code)
proc.stdin.flush()
output = proc.stdout.readline()

我希望output同时包含输出和任何错误消息。但是我无法使代码可靠地获得GHCI的输出

以下是.readline方法被阻塞的示例,即使已输入:


>>> from subprocess import Popen,STDOUT
>>> proc = Popen(["ghci","Session.hs"],stderr=STDOUT)
>>> for _ in range(7): proc.stdout.readline()
...
b'GHCi,version 8.6.3: http://www.haskell.org/ghc/  :? for help\r\n'
b'[1 of 5] Compiling Classes          ( Classes.hs,interpreted )\r\n'
b'[2 of 5] Compiling Functions        ( Functions.hs,interpreted )\r\n'
b'[3 of 5] Compiling Rule             ( Rule.hs,interpreted )\r\n'
b'[4 of 5] Compiling Graph            ( Graph.hs,interpreted )\r\n'
b'[5 of 5] Compiling Main             ( Session.hs,interpreted )\r\n'
b'Ok,five modules loaded.\r\n'
>>> proc.stdin.write("completeGraph 3".encode('utf-8'))
15
>>> proc.stdin.flush()
>>> output = proc.stdout.readline()
|

此外,GHCI希望在将提示*Main>发送到stdout之前进行输入,因为以下内容被阻止:

>>> from subprocess import Popen,stderr=STDOUT)
>>> for _ in range(8): proc.stdout.readline()
...
b'GHCi,five modules loaded.\r\n'
|

还有另一种方法会更成功吗?

解决方法

通过GHCI进行管道传输似乎非常脆弱。如果该库的API当前不适合FFI,我建议编写另一个(Haskell)库,将其包装并提供更适合您的API。然后通过Python的FFI而不是GHCI管道调用它。遍历文本永远不会很有趣。