地图不是很懒? [英] map not quite lazy?

查看:65
本文介绍了地图不是很懒?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

map似乎不像我想要的那么懒,在此示例中,map一次调用了该函数,就像我期望的那样:

map doesn't seem quite as lazy as I would like, in this example map calls the function one time as I would expect:

(first (map #(do (println "x: " %) %) '(0 1)))

但是在这两个示例中,它两次调用了该函数:

but in these two examples it calls the function two times:

(first (map #(do (println "x: " %) %) '[0 1]))
(first (map #(do (println "x: " %) %) (doall (range 2))))

选择是否懒惰的基本原则是什么?

What is the underlying principle for making the choice to be lazy or not?

有没有办法保证完全懒惰?

Is there a way to guarantee total laziness?

感谢您的时间.

推荐答案

Map(以及对集合起作用的类似HOF)对集合进行序列抽象处理:它从传递的集合(seq coll)创建一个序列,然后对之后返回序列. PersistentList('(0 1)PersistentList的实例)通过ASeq扩展实现ISeq,因此seq函数返回列表本身.在PersistentVector([1 2])的情况下,seq函数返回分块的序列(出于性能原因,它一步一步评估数据块(32个Elts),但仅返回所请求的元素;计算下一个分块当当前块耗尽时).

Map (and similar HOFs that work on collections) works on the sequence abstraction over collections: it creates a sequence from the passed collection (seq coll) and works on the returned sequence afterwards. PersistentList ('(0 1) is instance of PersistentList) implements ISeq through the ASeq extension, so seq function returns the list itself. In case of PersistentVector ([1 2]), the seq function returns a chunked sequence (performance reasons, it evaluates chunk (32 elts) of data in one step, but returns only the requested element; the next chunk is calculated when the current chunk is exhausted).

在测试此行为时,请尝试对count> 32的集合进行测试((vec (range 40))返回项目0-39的向量):

When testing this behaviour, try to test with collections with count > 32 ((vec (range 40)) returns a vector of items 0-39):

=> (first (map #(do (println "x: " %) %) (vec (range 40))))
x:  0
x:  1
x:  2
x:  3
...
x:  30
x:  31
0

如您所见,访问第一个元素时将评估整个块(元素0-31),而从下一个块中请求第一个元素时,将评估其余的元素(32-39).

As you can see, the whole chunk (elements 0-31) is evaluated when accessing the first element, the remaining elements (32-39) will be evaluated when requesting the first element from the next chunk.

如果是列表集合,则不使用分块的seq,并且仅评估第一项((apply list (range 40))返回项目0-39的列表):

In case of collections that are list, chunked seq is not used and only the first item is evaluated ((apply list (range 40)) returns a list of items 0-39):

=> (first (map #(do (println "x: " %) %) (apply list (range 40))))
x:  0
0

这篇关于地图不是很懒?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆