在clojure返回错误中实现范围函数

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在clojure返回错误中实现范围函数相关的知识,希望对你有一定的参考价值。

我试图在clojure中实现范围函数,但我的实现返回了一个我无法理解的错误。这里是:

(defn implement-range [a b] (
  if (= a b)
  (conj nil b)
  ((conj nil a) (implement-range (inc a) b))))

我试图以递归的方式做,它还没有完成,因为我遇到了这个错误:

ClassCastException clojure.lang.PersistentList cannot be cast to clojure.lang.IFn  user/implement-range

我认为这是一个我无法看到的括号问题(我是clojure的新手:))。有任何想法吗?

在此先感谢您的帮助

编辑:

如果我像这样调用函数,我想返回类似(1 2 3 4)的东西:

(implement-range 1 5)
答案

你很亲密:

(defn implement-range [a b]
  (if (>= a b)
      '()
      (conj (implement-range (inc a) b) a)))

(implement-range 0 5)
=> (0 1 2 3 4)

首先,主要问题是((conj nil a) (implement-range (inc a) b))))试图将(conj nil a)称为函数,以(implement-range (inc a) b)为参数。我不完全确定你在这里要做什么,但这绝对不是你想要的。

我做了三个改变:

  • 你需要conj当前的数字到递归调用的结果。这是“不安全”的递归,因为递归调用不在尾部位置,但在乱搞时,这不是什么大问题。如果您打算将其用于实际,则需要使用替代方法。
  • 如果输入大于ba,它将会爆炸。我通过改变基本情况来解决这个问题。
  • 你的基础案例没有任何意义。递归停止后,您将要添加到空列表。

只是一个旁注,任何时候你看到((,小闹铃应该会消失。这往往是一个问题的迹象,除非你得到幻想并写一些像((comp str inc) 1);表达式中的第一个表单求值为函数。

另一答案

最简单(也是最经典的)就是这样的:

(defn implement-range [a b]
  (when (< a b)
    (cons a (implement-range (inc a) b))))

user> (implement-range 1 20)
;;=> (1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19)
另一答案

我做了一些研究,发现使用conj这种方式没有任何意义。所以我想出了这个:

(defn implement-range [a b] (
  if (= a b)
  b
  (flatten (list a (implement-range (inc a) b)))))

因此,如果我使用1 4参数调用该函数,结果将是:

(1 2 3 4)

但是,因为我试图实现像range函数这样的函数,所以它还需要删除最后一个元素。

编辑1

我写的最后一个函数看起来像这样:

(defn implement-range [a b] (
  if (= a b)
  nil
  (remove nil? (flatten (list a (implement-range (inc a) b))))))

编辑2经过一些更多的研究后,我找到了解决这个问题的另一种方法,用更少的代码行:

(defn new-range [a b]
  (take (- b a) (iterate inc a)))

以上是关于在clojure返回错误中实现范围函数的主要内容,如果未能解决你的问题,请参考以下文章

如何在clojure期望中实现fixture?

在 Laravel 4 中实现 Remember Me 函数会返回错误

尝试在片段中实现 OnClick 侦听器 [重复]

在我的应用程序中实现搜索时出现错误“索引 6 超出范围 [0 .. 5]”

clojure 函数,左值和返回值

Android,列表适配器在getView中返回错误的位置