初学者Clojurist Lazy Sequence错误:不知道如何从java.lang.Long创建ISeq

时间:2016-05-04 19:16:13

标签: clojure lisp

我是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)

为什么我收到此错误?如果我理解正确,那么应该能够对延迟序列进行处理,并且应该返回序列的前十个值,递归计算。

4 个答案:

答案 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,则会发生两件事:

  1. 将评估符号geometric,这将产生geometric功能。
  2. 将返回1号。
  3. 你可能的意思是:

    ([] (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)的第二个参数的序列。