Clojure “迭代”和“重复”之间的区别`
我是clojure/clojurescript的新手,我试图弄明白为什么这个函数总是返回100作为第一个随机整数,最后返回几个零:Clojure “迭代”和“重复”之间的区别`,clojure,clojurescript,Clojure,Clojurescript,我是clojure/clojurescript的新手,我试图弄明白为什么这个函数总是返回100作为第一个随机整数,最后返回几个零: (take 10 (iterate rand-int 100)) ;; (100 30 19 15 4 3 2 0 0 0) 但这是意料之中的: (take 10 (repeatedly #(rand-int 100))) ;; (14 14 16 92 10 69 85 74 65 95) 但是如果我使用匿名fn和iterate一起使用,我会得到nil作为第一
(take 10 (iterate rand-int 100))
;; (100 30 19 15 4 3 2 0 0 0)
但这是意料之中的:
(take 10 (repeatedly #(rand-int 100)))
;; (14 14 16 92 10 69 85 74 65 95)
但是如果我使用匿名fn和iterate
一起使用,我会得到nil
作为第一个值,但其余的看起来没问题:
(take 10 (iterate #(rand-int 100)))
;; (nil 27 19 76 70 40 63 72 32 55)
iterate
返回序列(x(fx)(f(fx))…)
因此第一个元素是您提供的100
。第二个元素是(rand int 100)
的结果,它返回范围(0,99)
内的随机数。在这种情况下,它返回30
,因此第三个元素是(rand int 30)
的结果,它返回范围(0,29)
。由于范围正在缩小,生成的数字迅速接近0
相反,
重复地返回序列((f)(f)(f)…)
,其中f
是一个没有参数的函数,如#(rand int 100)
,其中生成的数字的范围总是(0,99)
f
预计会有一些副作用(修改随机数生成器的状态)迭代
返回序列(x(fx)(f(fx))…)
因此第一个元素是您提供的100
。第二个元素是(rand int 100)
的结果,它返回范围(0,99)
。在这种情况下,它返回30
,因此第三个元素是(rand int 30)
的结果,它返回范围(0,29)
内的元素。由于范围在缩小,生成的数字迅速接近0
相反,重复地返回序列((f)(f)(f)…)
,其中f
是一个没有参数的函数,如#(rand int 100)
,其中生成的数字的范围总是(0,99)
f
预计会有一些副作用(修改随机数生成器的状态)太棒了。我确实读了文档,但不太明白。您说得很清楚。谢谢。太棒了。我确实读了文档,但不太明白。您说得很清楚。谢谢。您的第三个示例中一定有输入错误;我得到:ArityException错误的参数数(1)传递给:core/iterate clojure.lang.AFn.throwArity(AFn.java:429)
@AlanThompson,这不是打字错误,而是我缺乏知识。但是它在lumo
repl中为我工作,并警告:警告:在第1行传递给cljs.core/iterate的参数(1)数量错误(nil 6 76 80 10 88 15 38 60)
@AlanThompson注意,问题是关于cljs的,您在JVM上尝试过,JVM对调用函数的合理方式有更严格的定义。javascript处理缺少的参数的方式(大致)是假装为零,多余的参数被忽略。因此第三个示例实际上是(以10为例(迭代(fn[\ux])(rand int 100))nil()
,很明显,它的行为将与此问题报告的方式完全相同。您的第三个示例中一定有输入错误;我得到:ArityException错误的参数数(1)传递给:core/iterate clojure.lang.AFn.throwArity(AFn.java:429)
@AlanThompson,这不是一个拼写错误,而是我缺乏知识。但是它确实在lumo
repl中为我工作,并带有一个警告:warning:cljs.core/iterate在第1行传递了错误的参数(1)(nil 6 76 80 37 10 88 15 38 60)
@AlanThompson注意,问题是关于cljs的,您在JVM上尝试过,JVM对调用函数的合理方式有更严格的定义。javascript处理缺少的参数的方式(大致)是假装为零,多余的参数被忽略。因此第三个示例实际上是(以10为例(迭代(fn[\ux])(rand int 100))nil)
,很明显,它的行为将与此问题报告的方式完全相同。