【问题标题】:laziness in action? (Haskell)行动中的懒惰? (哈斯克尔)
【发布时间】:2012-06-26 18:40:19
【问题描述】:

Learn You a Haskell的第6章,介绍了如下函数:

zipWith' :: (a -> b -> c) -> [a] -> [b] -> [c]
zipWith' _ [] _ = []
zipWith' _ _ [] = []
zipWith' f (x:xs) (y:ys) = f x y : zipWith' f xs ys

作者给出了几个我觉得很容易理解的例子。然后这个:

ghci> zipWith' (zipWith' (*)) [[1,2,3],[3,5,6],[2,3,4]] [[3,2,2],[3,4,5],[5,4,3]]

哪个输出[[3,4,6],[9,20,30],[10,12,12]]

这是惰性求值的例子吗?我试图将 zipWith' 翻译成 Scheme(见下文)。我用“简单”的例子来工作,但不是最后一个,这让我认为 Haskell 的懒惰可能会有所作为。

(define zipWith
  (lambda (f listA listB)
    (cond
      ((null? listA) (quote ()))
      ((null? listB) (quote ()))
      (else (cons (f (car listA) (car listB)) (zipWith f (cdr listA) (cdr listB)))))))

【问题讨论】:

  • 不,这不是懒惰。它使用部分应用程序,这在Scheme中可能有点不重要(或者不是,我不太了解Scheme)。
  • 我认为 Daniel Fischer 是对的。 Currying 显然可以用宏 phyast.pitt.edu/~micheles/scheme/scheme14.html 来模拟
  • @jberryman:我认为该链接正是我所需要的。如果您将此作为答案发布,我将很高兴为您服务!
  • @Planarian:你不需要任何宏。手动做部分应用并不难(lambda (x y) (zipWith * x y))

标签: haskell scheme lazy-evaluation higher-order-functions partial-application


【解决方案1】:

不,虽然这个例子会被延迟评估(就像 Haskell 中的任何其他函数一样),但行为并不依赖于此。在有限列表上,它的行为与急切评估相同。当然,在无限列表上,它永远不会因急切求值而终止,但惰性求值允许您只求值所需数量的列表元素。

如果您发布用于调用最后一个示例的 Scheme zipWith 的代码,也许我们可以帮助您了解为什么会有不同的行为。

【讨论】:

    【解决方案2】:

    zipWith' (*) [1,2,3] [1..] 会(使用)懒惰地评估

    【讨论】:

      【解决方案3】:

      jberryman 的link 在对我的原始帖子的评论中提供了最全面的答案。感谢所有回复的人。

      (edit-in: 正如@newacct 在 cmets 中提到的那样,通过显式 lambda 构造,(lambda (x y) (zipWith * x y)) 可以轻松实现部分应用。Lambdas 非常 basic 在 Scheme 中,我们不需要 宏。)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-01-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-24
        • 1970-01-01
        相关资源
        最近更新 更多