【问题标题】:Why doesn't this Haskell I translated to Python work properly?为什么我翻译成 Python 的这个 Haskell 不能正常工作?
【发布时间】:2011-08-25 06:40:53
【问题描述】:

哈斯克尔:

average x y = (x + y) / 2

sqrt' :: (Ord a, Fractional a) => a -> Int -> a
sqrt' 0 _ = 0.0
sqrt' 1 _ = 1.0
sqrt' s approximations = (infsqr' s) !! approximations

infsqr' n = unfoldr acc 1 where
    acc guess | guess < 0 = Nothing
              | otherwise = Just (newguess', newguess') where
                newguess' = average guess (n / guess)

Python:

def unfold(f, x):
    while True:
        w, x = f(x)
        yield w

def average(x, y):
    return float((x + y) / 2)

def acc(guess):
    if guess < 1:
        return None
    else:
        newguess = average(guess, (float(n/guess)))
        return (newguess, newguess) 
n = 9
print unfold(acc, 1).next()
print unfold(acc, 1).next()

它应该输出列表的下两个值,例如5.0、3.4

但它输出了两次 5.0,为什么?

【问题讨论】:

    标签: python math haskell


    【解决方案1】:

    如果您再次调用展开,您的生成器将再次重新生成,因此您需要将其分配给变量。

    >>> res = unfold(acc, 1)
    >>> print res.next()
    5.0
    >>> print res.next()
    3.4
    >>>
    

    【讨论】:

    • 所以生成器不会在调用 .next() 之间保持状态,除非我给它一个名字?谢谢,我没有意识到这一点。
    • @Wes 这不是正确的思考方式。 unfold 是一个返回生成器的函数,特别是每次调用时都会返回一个新生成器。如果你创建了一个生成器,在它上面调用 .next(),然后扔掉它,它的所有状态都消失了。
    • 啊,有道理。因为如果我要打印函数的返回值,我会得到一个生成器类型。我现在明白了。
    猜你喜欢
    • 2021-01-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-30
    • 2023-02-20
    • 1970-01-01
    • 2022-10-23
    • 1970-01-01
    相关资源
    最近更新 更多