从Python生成并运行Haskell代码

2024-05-21 04:50:28 发布

您现在位置:Python中文网/ 问答频道 /正文

我们正在编写一个python程序,它尝试在给定输入输出对的情况下合成一个(简单的)haskell函数。在整个程序的运行过程中,我们生成haskell代码,并对照用户提供的示例检查其正确性。 假设我们得到输入“12”和预期输出“3”。我们会(最终) 想出加号函数。然后我们就跑 (\x y -> x + y) 1 2并检查它的计算结果是否为3。在

我们目前的做法是运行以下python代码:

from subprocess import Popen, PIPE, STDOUT
proccess = Popen(f'ghc -e "{haskell_code}"', shell=True, stdout=PIPE, stderr=STDOUT) 
haskell_output = proc.stdout.read().decode('utf-8').strip('\n')

由于我们都不熟悉ghc、haskell、流程或与此相关的任何内容,我们希望有人能帮助我们以(非常)高效的方式完成这项任务,因为目前进展非常缓慢。在

此外,我们希望能够执行不止一个语句。例如,我们想进口数据字符这样我们的函数就可以使用“toUpper”。但是,我们目前的做法是发送一个lambda函数及其附加的输入,我们不确定如何在上面添加import语句(添加“\n”似乎不起作用)。在

总而言之,我们需要最快的(运行时)解决方案,它允许我们从python测试haskell函数(我们不需要提前或在某个时间点测试所有haskell函数的代码,而是在生成代码时进行测试),同时允许我们使用多个语句(例如,导入)。在

抱歉,如果这是微不足道的或愚蠢的,任何帮助将不胜感激。在


Tags: 函数代码用户import程序haskell过程stdout
1条回答
网友
1楼 · 发布于 2024-05-21 04:50:28

这似乎是一件奇怪的事。。但有趣的是。在

这里马上想到两件事。第一种方法是使用ghci repl,而不是为每次eval尝试生成一个新进程。其思想是将您的I/O流式传输到ghci进程中,而不是为每次尝试生成一个新的ghc进程。为每次评估启动一个新流程的开销似乎是相当高的性能杀手。我通常会选择expect,但是由于您需要python,所以我将调用pexpect

import pexpect
import sys
from subprocess import Popen, PIPE, STDOUT
import time


REPL_PS = unicode('Prelude> ')
LOOPS = 100


def time_function(func):
    def decorator(*args, **kwargs):
        ts = time.time()
        func(*args, **kwargs)
        te = time.time()
        print "total time", (te - ts)
    return decorator


@time_function
def repl_loop():
    repl = pexpect.spawnu('ghci')
    repl.expect(REPL_PS)
    for i in range(LOOPS):
        repl.sendline('''(\\x y -> x + y) 1 2''')
        _, haskell_output = repl.readline(), repl.readline()
        repl.expect(REPL_PS)


@time_function
def subproc_loop():
    for i in range(LOOPS):
        proc = Popen('''ghc -e "(\\x y -> x + y) 1 2"''', shell=True, stdout=PIPE, stderr=STDOUT) 
        haskell_output = proc.stdout.read().decode('utf-8').strip('n')
        # print haskell_output


repl_loop()
subproc_loop()

这给了我一个非常一致的速度提升。在

有关详细信息,请参阅pexpect doc:https://github.com/pexpect/pexpect/

第二个直接的想法是使用一些分布式计算。我没有时间在这里建立全面的演示,但有许多伟大的例子已经生活在互联网的土地上,等等。其思想是让多个“python+ghci”进程从一个公共队列读取eval attempts,然后将结果推送到一个公共的eval attempt checker。在多线程的情况下,需要多个GHT并行进程来进行检查,但GHI并不需要多个线程。在

这里可能有一些有趣的链接:

How to use multiprocessing queue in Python?

https://docs.python.org/2/library/multiprocessing.html

https://eli.thegreenplace.net/2012/01/24/distributed-computing-in-python-with-multiprocessing

相关问题 更多 >