懒惰在行动?(Haskell的)

pla*_*ian 3 scheme haskell partial-application lazy-evaluation higher-order-functions

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
Run Code Online (Sandbox Code Playgroud)

作者给出了几个使用它的例子,我发现它很容易遵循.然后这个:

ghci> zipWith' (zipWith' (*)) [[1,2,3],[3,5,6],[2,3,4]] [[3,2,2],[3,4,5],[5,4,3]]
Run Code Online (Sandbox Code Playgroud)

哪个输出 [[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)))))))
Run Code Online (Sandbox Code Playgroud)

Dan*_*lme 5

不,虽然这个例子将被懒惰地评估(就像Haskell中的任何其他函数一样),但行为并不依赖于此.在有限列表上,它会以热切的评估方式表现出相同的行为.当然,在无限列表中,它永远不会以急切的评估结束,但是延迟评估允许您只根据需要评估列表元素.

如果你发布了你用来调用最后一个例子的Scheme zipWith的代码,也许我们可以帮助看看为什么这种行为有所不同.