clojure - Clojure apply 没有实现惰性序列的前四个元素?
问题描述
看起来 apply 强制实现给定惰性序列的四个元素。
(take 1
(apply concat
(repeatedly #(do
(println "called")
(range 1 10)))))
=> "called"
=> "called"
=> "called"
=> "called"
有没有办法做一个不这样的申请?
谢谢你
解决方案
有没有办法做一个
apply
不这样的行为?
我认为简短的回答是:必须重新实现 Clojure 的一些基本功能。的实现直接依赖于 Clojure 的可调用函数的实现,并尝试通过枚举参数的输入序列apply
来发现给定函数的正确性。.invoke
在惰性、未分块的序列/reducers/transducers 上使用函数而不是使用带有apply
. 例如,这是您使用传感器重新实现的示例,它只调用一次 body 函数(每个长度range
):
(sequence
(comp
(mapcat identity)
(take 1))
(repeatedly #(do
(println "called")
(range 1 10))))
;; called
;; => (1)
apply
用, concat
, seq
,LazySeq
等深入了解您的示例中发生的情况:
repeatedly
返回一个新LazySeq
实例:(lazy-seq (cons (f) (repeatedly f)))
.- 对于给定的 2-arity
(apply concat <args>)
,apply
调用RT.seq
其参数列表,对于 aLazySeq
then 调用LazySeq.seq
,这将调用您的函数 apply
然后调用一个Java impl。applyToHelper
尝试获取参数序列长度的方法。applyToHelper
尝试使用 来确定参数列表的长度RT.boundedLength
,它内部调用next
andseq
,因此它可以找到适当的重载IFn.invoke
to 调用concat
本身增加了另一层lazy-seq
行为。
您可以看到这些调用的堆栈跟踪,如下所示:
(take 1
(repeatedly #(do
(clojure.stacktrace/print-stack-trace (Exception.))
(range 1 10))))
第一个跟踪来自apply
的初始调用seq
,随后的跟踪来自RT.boundedLength
.
推荐阅读
- ios - 如何将 NSData 从 javascript 传递到 swift 5?
- wordpress - WordPress 联系表格 7 无需插件即可进入数据库
- javascript - 以编程方式打开 d3.js v4 可折叠树节点?
- c# - 如何将旧代码从不同的命名空间导入到我当前的项目中?
- r - 如何通过 ABCD 计算频率 AMT?
- reactjs - 当嵌套状态用作值时,选择标签被禁用
- javascript - 如何使用自定义选择下拉列表过滤项目?
- java - 将“String[][] gameState=new String[10][10]”保存到sql
- node.js - 如何创建功能读取和发布二进制文件,如 NodeJS 的 PostMan?
- c# - 如何将十进制(或浮点)转换为二进制?C#