python - 将 Haskell 代码转换为 Python 或伪代码

标签 python haskell

我正在研究 an algorithm .但是我对作者提供的haskell代码不是很清楚,所以我需要你们的帮助。 我认为代码可以分为两部分。

> type LFT = (Integer, Integer, Integer, Integer)
>
> extr :: LFT -> Integer -> Rational
> extr (q,r,s,t) x = ((fromInteger q) * x + (fromInteger r)) / ((fromInteger s) * x + (fromInteger t))
>
> unit :: LFT
> unit = (1,0,0,1)
>
> comp :: LFT -> LFT -> LFT
> comp (q,r,s,t) (u,v,w,x) = (q*u+r*w,q*v+r*x,s*u+t*w,s*v+t*x)

这里,很明显,定义了一个名为 LFT 的类型(可能是 Python 中的一个元组)和三个名为 extr unit comp 的函数。然而,接下来的部分让我很困惑:

> pi = stream next safe prod cons init lfts where
>   init = unit
>   lfts = [(k, 4*k+2, 0, 2*k+1) | k<-[1..]]
>   next z = floor (extr z 3)
>   safe z n = (n == floor (extr z 4))
>   prod z n = comp (10, -10*n, 0, 1) z
>   cons z z’ = comp z z’

我相信 lfts 是一个生成器,但我无法理解这段代码中的循环是如何执行的,而且我对 Haskell 了解不多。你能帮我把这个转换成 Python 或伪代码吗?

最佳答案

首先 lfts 是一个无限列表。您可以使用 itertools.count 编写非常相似的代码:

from itertools import count

# count(1) is "equivalent2 to [1..]
lfts = ((k, 4*k+2, 0, 2*k+1) for k in count(1))

现在代码的重要部分是对 stream 的调用,这是一个“执行循环”的函数。该函数在文章中定义为:

> stream :: (b->c) -> (b->c->Bool) -> (b->c->b) -> (b->a->b) ->
>           b -> [a] -> [c]
> stream next safe prod cons z (x:xs)
>   = if   safe z y
>     then y : stream next safe prod cons (prod z y) (x:xs)
>     else stream next safe prod cons (cons z x) xs
>       where y = next z

stream 的思想是:

  • 最后一个参数 (x:xs) 是一个(无限)输入列表([a] 类型)
  • 倒数第二个参数 (z) 是某种形式的state(b 类型)
  • 其他四个参数是操作输入和状态的函数:

    • next 函数接受一个状态并产生一个输出 (y)。
    • safe 函数检查是否应该在输出中添加y
    • prod 函数产生新状态
    • y添加到输出时调用 cons 函数,用于从输入生成新状态值 x

您可以重现这样的功能:

import itertools as it

def stream(nxt, safe, prod, cons, state, inputs):
    x = next(inputs)   # obtain x
    # xs = inputs
    y = nxt(state)
    if safe(state, y):
        yield y
        inputs = it.chain([x], inputs)   # put x back in the input
        yield from stream(nxt, safe, prod, cons, prod(state, y), inputs)
    else:
        yield from stream(nxt, safe, prod, cons, cons(state, x), inputs)

所以基本上它所做的是从某个状态开始产生一些值。当它达到某个条件时,它会消耗一个输入值来产生一个新的状态并产生更多的值,当它再次停止时它会使用另一个输入值再次产生一个新的状态等等。无穷无尽。

请注意,上述实现的性能非常差。最好避免 python 中的递归,所以我会使用:

def stream(nxt, safe, prod, cons, state, inputs):
    while True:
        x = next(inputs)   # obtain x
        # xs = inputs
        y = nxt(state)
        if safe(state, y):
            yield y
            inputs = it.chain([x], inputs)   # put x back in the input
            state = prod(state, y)
        else:
            state = cons(state, x)

关于python - 将 Haskell 代码转换为 Python 或伪代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36955891/

相关文章:

python - uWSGI + Docker : pyuwsgi: executable file not found in $PATH

python - 如何让 Python-Telegram Bot 在没有收到命令的情况下发送消息?

list - 在haskell中创建循环列表的三种方法

python - 如何从已有的相关数据创建关联数据框

python - 如何拆分逗号和点?

python - 如何让 Python 拒绝负索引值?

haskell - 从元组的元组中提取元组 Haskell

haskell - 如何仅用一个函数解决此数据类型问题,最好使用模式匹配

haskell - 我可以减少 ghci 的内存使用量吗?

haskell - 如何找到最优的加工顺序?