Connecting a Haskell program to a Python program through Pipelines (in Python)

Feel me, as I'm pretty new to programming. My main question is this. I have a program written in Haskell whose stdout I want to connect to the stdin of a Python program (which will manage GUI-related stuff). Similarly, I want to associate the stdout of a Python program with the stdin of a Haskell program so that it can send information about what the user pressed / typed in the Haskell program.

The first question is that if I set up a pipeline between them, assuming that the stdout of the Python program is connected to the Haskell program, if I use Tkinter to create widgets, etc., will they still be displayed on the screen?

The second question: how exactly can I install this conveyor? Consider the following code example.

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 code will look something like this.

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.

I apologize if this has already been asked before, but thanks for helping me!

+5
source share
2 answers

I did this with Twisted , as it provides an excellent abstraction over the survey. Basically you need to first determine how (called the protocol in Twisted) how Python and Haskell communicate with each other, such as how long a data packet takes, how to handle errors, etc. Then you just encode them.

Here is the haskell code:

-- 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

And here is the Python code:

# 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 (and twisted's) mainloop
reactor.run()                                                                                                           
+1
source

You can also install the pipeline from the shell:

mypython.py | myhaskell.hs

Haskell , , :

myhaskell.hs

-2

All Articles