我是Clojure和Lisp的新手,但到目前为止一直很喜欢它。我目前正在尝试理解lazy-seq和Clojure定义无限序列的能力。我有以下代码:
(defn geometric
([] geometric 1)
([n] (cons n (lazy-seq (geometric (* n 1/2))))))
如果我跑:
(geometric)
在我的REPL中,它按预期返回1。但是,如果我跑,
(take 10 (geometric))
我收到以下错误:
IllegalArgumentException Don't know how to create ISeq from:
java.lang.Long clojure.lang.RT.seqFrom
我期望得到的是:
(1 1/2 1/4 1/8 1/16 1/32 1/64 1/128 1/256 1/512)
为什么我收到此错误?如果我理解正确,那么应该能够对延迟序列进行处理,并且应该返回序列的前十个值,递归计算。
答案 0 :(得分:4)
我最喜欢的功能之一:UIView
使用函数iterate
和值f
返回x
等。
这是一个具有相同功能的优雅实现:
x, (f x), (f (f x), (f (f (f x)))
不是您问题的直接答案,但希望能提供丰富的信息!
答案 1 :(得分:2)
您的代码中有一个小错字:
popularityChartView.descriptionText = ""
popularityChartView.noDataText = Constants.messages.NO_POPULARITY_CHART_DATA
popularityChartView.noDataTextDescription = ""
popularityChartView.backgroundColor = UIColor(red:236/255, green:236/255,blue:236/255,alpha:1)
popularityChartView.xAxis.drawAxisLineEnabled = false
popularityChartView.xAxis.drawLimitLinesBehindDataEnabled = false
popularityChartView.xAxis.gridColor = UIColor(red:220/255, green:220/255,blue:220/255,alpha:1)
popularityChartView.xAxis.gridLineWidth = 0.5
popularityChartView.xAxis.drawGridLinesEnabled = true
popularityChartView.xAxis.drawLabelsEnabled = false
popularityChartView.leftAxis.removeAllLimitLines()
popularityChartView.leftAxis.drawZeroLineEnabled = false
popularityChartView.leftAxis.zeroLineWidth = 0
popularityChartView.leftAxis.drawTopYLabelEntryEnabled = false
popularityChartView.leftAxis.drawAxisLineEnabled = false
popularityChartView.leftAxis.drawGridLinesEnabled = false
popularityChartView.leftAxis.drawLabelsEnabled = false
popularityChartView.leftAxis.drawLimitLinesBehindDataEnabled = false
popularityChartView.rightAxis.removeAllLimitLines()
popularityChartView.rightAxis.drawZeroLineEnabled = false
popularityChartView.leftAxis.zeroLineWidth = 0
popularityChartView.rightAxis.drawTopYLabelEntryEnabled = false
popularityChartView.rightAxis.drawAxisLineEnabled = false
popularityChartView.rightAxis.drawGridLinesEnabled = false
popularityChartView.rightAxis.drawLabelsEnabled = false
popularityChartView.rightAxis.drawLimitLinesBehindDataEnabled = false
如果没有这个修复(defn geometric
([] (geometric 1)) ;; notice the added parens around geometric 1
([n] (cons n (lazy-seq (geometric (* n 1/2))))))
正在运行,因为实现是为了评估被丢弃的表达式(geometric 1)
(只是一个函数值),然后评估geometric
表达式并作为函数结果返回(这是这个arity函数体中的最后一个表达式。)
现在它按预期工作:
1
请注意,您不能只在REPL中安全地调用(take 1 (geometric))
;; => (1)
(take 5 (geometric))
;; => (defn geometric
([] geometric 1)
([n] (cons n (lazy-seq (geometric (* n 1/2))))))
,因为它会尝试评估无限序列。
答案 2 :(得分:2)
你的问题在这里:
([] geometric 1)
这个表达式意味着,如果在没有参数的情况下调用geometric
,则会发生两件事:
geometric
,这将产生geometric
功能。1
号。你可能的意思是:
([] (geometric 1))
这意味着调用(geometric)
等同于调用(geometric 1)
。您的示例现在将按预期工作:
(take 10 (geometric))
;=> (1 1/2 1/4 1/8 1/16 1/32 1/64 1/128 1/256 1/512)
答案 3 :(得分:1)
(geometric)
评估数字1,而不是序列。 (geometric)
会出现您现在看到的相同错误。
您应该尝试运行(take 10 1)
,因为(take 10 (geometric 1))
将生成一个可以提供给(geometric 1)
的第二个参数的序列。