5

私はプログラミングにかなり慣れていないので、我慢してください。私の基本的な質問はこれです。私はHaskellで書かれたプログラムを持っており、そのstdoutをPythonプログラムのstdinに接続したいと思っています(GUI関連のものを管理します)。同様に、PythonプログラムのstdoutをHaskellプログラムのstdinに接続して、ユーザーがクリック/入力した内容に関する情報をHaskellプログラムに送信できるようにします。

最初の質問は、PythonプログラムのstdoutがHaskellプログラムに接続されていると仮定して、2つの間にパイプラインを設定した場合、Tkinterを使用してウィジェットなどを作成した場合でも、それらは画面に表示されますか?

2番目の質問は、このパイプラインをどの程度正確に確立するかということです。次のサンプルコードを考えてみましょう。

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.

これまでに質問されたことがある場合は申し訳ありませんが、私を助けてくれてありがとう!

4

2 に答える 2

1

ポーリングよりも優れた抽象化を提供するため、Twistedを使用して実行しました。基本的に、最初にPythonプログラムとHaskellプログラムが相互に通信する方法(たとえば、データパケットの長さ、エラーの処理方法など)を定義する必要があります。次に、それらをコーディングするだけです。

これが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()                                                                                                           
于 2013-03-18T09:54:43.713 に答える
-2

コマンドシェルからパイプラインを確立することもできます。

mypython.py | myhaskell.hs

Haskellプログラムは、次のように、他のタイプの標準入力と同じように応答します。

myhaskell.hs

于 2013-03-18T04:02:51.997 に答える