通过管道将Haskell程序连接到Python程序(在Python中)



请原谅我,因为我对编程相当陌生。我的基本问题是。我有一个用Haskell编写的程序,我想将其标准输出连接到Python程序的标准输入(它将管理GUI相关的东西)。类似地,我想将Python程序的标准输出连接到Haskell程序的标准输入,这样它就可以向Haskell程序发送有关用户点击/输入内容的信息。

第一个问题是,如果我在两者之间建立一个管道,假设Python程序的stdout连接到Haskell程序,如果我使用Tkinter创建小部件和东西,它们会显示在屏幕上吗?

第二个问题是我究竟如何建立这个管道?考虑下面的示例代码..

main :: IO ()
main = do
    -- putStrLn "Enter a number." <- this will be displayed in Python
    string <- getLine
    putStrLn $ 5 + read string::Int -- or any equivalent function to send to stdout

Python代码应该是这样的:

from Tkinter import *
root = Tk()
label = Label(root, text = "Enter a number.")
label.pack()
enternum = Entry(root)
enternum.pack()
enternum.bind("<Return>", print_num)
-- print_num would essentially be a function to send the Haskell program the number
-- which would be received by the getLine function the way I have it.
我很抱歉,如果这个问题已经被问过了,但是谢谢你的帮助!

我使用Twisted,因为它对轮询提供了很好的抽象。基本上,你需要首先定义Python和Haskell程序如何相互通信的方式(在Twisted中称为协议),例如,数据包有多长,如何处理错误等。然后把它们编码起来。

下面是haskell代码:

-- File "./Hs.hs"
import Control.Concurrent                                                   
import System.IO
main = do
  -- Important
  hSetBuffering stdout NoBuffering
  -- Read a line
  line <- getLine
  -- parse the line and add one and print it back
  putStrLn (show (read line + 1))
  -- Emphasize the importance of hSetBuffering :P
  threadDelay 10000000

下面是Python代码:

# File "./pyrun.py"
import os                                                                   
here = os.path.dirname(os.path.abspath(__file__))
from twisted.internet import tksupport, reactor, protocol
from twisted.protocols.basic import LineReceiver
from Tkinter import Tk, Label, Entry, StringVar
# Protocol to handle the actual communication
class HsProtocol(protocol.ProcessProtocol):
    def __init__(self, text):
        self.text = text
    def connectionMade(self):
        # When haskell prog is opened
        towrite = self.text + 'n'
        # Write a line to the haskell side
        self.transport.write(towrite)
    def outReceived(self, data):
        # When haskell prog write something to the stdout
        # Change the label in the tk window to be the received data
        label_var.set(data[:-1])
def send_num_to_hs(_event):
    content = enternum.get()
    # The abspath of the haskell program
    prog = os.path.join(here, 'Hs')
    reactor.spawnProcess(HsProtocol(content), # communication protocol to use                                           
                         prog, # path
                         [prog] # args to the prog
                         )
# Setting up tk
root = Tk()
# On main window close, stop the tk reactor
root.protocol('WM_DELETE_WINDOW', reactor.stop)
# Since I'm going to change that label..
label_var = StringVar(root, 'Enter a number')
# Label whose content will be changed
label = Label(root, textvariable=label_var)
label.pack()
# Input box
enternum = Entry(root)
enternum.pack()
enternum.bind('<Return>', send_num_to_hs)
# Patch the twisted reactor
tksupport.install(root)
# Start tk's (and twisted's) mainloop
reactor.run()                                                                                                           

您也可以从命令shell中建立管道:

mypython.py | myhaskell.hs

Haskell程序的响应将与

相同任何其他类型的标准输入,如:

myhaskell.hs

相关内容

  • 没有找到相关文章

最新更新