在了解你的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)))))))
答案 0 :(得分:5)
不,虽然这个例子将被懒惰地评估(就像Haskell中的任何其他函数一样),但行为并不依赖于此。在有限列表上,它会以热切的评估方式表现出相同的行为。当然,在无限列表中,它永远不会以急切的评估结束,但是懒惰的评估允许您只根据需要评估列表元素。
如果您发布了用于调用最后一个示例的Scheme zipWith的代码,也许我们可以帮助了解为什么行为方式不同。
答案 1 :(得分:2)
zipWith' (*) [1,2,3] [1..]
将(使用)懒惰地评估
答案 2 :(得分:2)
jberryman的link在对我原帖的评论中提供了最全面的答案。感谢所有回复的人。
( 编辑: ,因为@newacct在评论中提及,部分应用程序通过明确的lambda
构造(lambda (x y) (zipWith * x y))
轻松实现。 Lambdas在Scheme中非常基本,我们不需要需要宏。)