热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Haskell中的`map`是懒惰的吗?

我一直在研究GrahamHutton的Haskell编程。它指出该函数map将函数应用于列表的所有元素

我一直在研究 Graham Hutton 的 Haskell 编程。它指出

该函数map将函数应用于列表的所有元素

好的,有道理。当然符合我对其他语言地图的了解。

练习之一是实施all :: (a -> Bool) -> [a] -> Bool

有时,如果不是懒惰地完成,一个幼稚的实现可能会无限循环。例如all (<10) [1..]。所以我的第一个实现是:

all p [] = True
all p (x:xs) | not (p x) = False
| otherwise = all' p xs

但后来我想到了用函数组合尝试mapand看什么在Haskell非终止的程序会怎么做:

all' :: (a -> Bool) -> [a] -> Bool
all' p = and . map p

出乎我的意料,all' (<10) [1..]很快就回来了False。我实际上希望mapand应用之前尝试创建一个无限列表- 类似于and [p x | x <- xs, p x].

这种终止行为意味着map实际上正在创建类似于and正在处理的流的东西。map 实际上是懒惰的(因此描述错误)还是我在第二个实现中误解了其他东西?

回答

map其实懒惰(因此说明错误的),或在我的第二个实现我误解了什么东西?

map很懒。它不会急切地将该功能应用于每个项目。事实上,所有的表达都在一定意义懒map f x仍然map f xs除非需要的价值。

如果我们评估map f xs,并且我们需要例如第三个元素,它不会确定我们是否对第一个元素的不感兴趣。f x1

列表理解也很懒惰。事实上,如果我们与:

and [p x | x <- xs]

它将从项目的那一刻起一个终止xxsFalse作为p x。然而p x,如果你添加一个 filter ,它只会发出Trues,确实:

[p x | x <- xs, p x]

只会 yield True,因为我们已经过滤了p x应该为的事实True,并且sand无限列表中True的 永远不会终止,因为and它将继续寻找一个False值。






推荐阅读
author-avatar
汽车一族coolboy_518
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有