Clojure 初学者在这里。无法弄清楚为什么函数没有按预期创建列表

Clojure beginner here. Cannot figure out why function is not creating list as expected

提问人:Braden Christopher 提问时间:10/12/2023 更新时间:10/12/2023 访问量:108

问:

我正在尝试将嵌套向量添加到映射中,即({:cells {[x y]})。我尝试以多种方式做到这一点,但无论我尝试什么,我都无法让它工作。我一直得到“传递给的参数数量错误(0):clojure.lang.PersistentArrayMap”,或者在另一种情况下,我什至无法让我的剩余函数,即(coordinates-gen)编译它。我必须手动重新输入它们才能让 REPL 识别它们。总的来说,我真的是严肃编码的初学者,所以我不知道该去哪里求助。这是我的函数:

(defn values-manual [grid values]
  (let [inter (interleave (coordinates-gen grid) [values])]
    (loop [[x y & remaining] inter]
      do(
         (assoc grid :cells (x y))
         (recur remaining)))))

我选择将两个向量(网格和值)交错在一起,因为它们的大小可能不同,并且交错会自动截断到较小的向量,这对于我的输出来说是可取的。然后,我访问此列表的前两个元素。然后将它们与我的“网格”映射中的 :cells 键相关联。然后对其余元素重复上述步骤。一旦我尝试运行它,它就不会起作用,并且我无法识别我的其他定义函数。我还使用了 do(),因为我可以验证循环是否适用于多个函数。这是怎么回事?非常感谢任何帮助。

我尝试了我能想到的一切。这是我的第一个大型编码项目。

Clojure Lisp

评论

0赞 Martin Půda 10/12/2023
您能否描述一下您正在尝试解决的整个问题,并提供一些示例数据和预期结果?我们甚至不知道函数做什么(或应该做什么)。它可以帮助您将问题分解为更小的部分,并在 REPL 中逐一测试它们——这甚至不是 Clojure 语法。coordinates-gendo()
0赞 cfrick 10/12/2023
如果将坐标生成为成对且不平坦,则可以将坐标与值zipmap

答:

6赞 Sean Corfield 10/12/2023 #1

由于您发布的代码不会编译 - 它会产生 - 我将假设您的意思是而不是.Syntax error: Can only recur from tail position(dodo(

修复它不会产生您看到的错误,但我怀疑会导致 .((assoc grid :cells (x y)))Wrong number of args (0) passed to: clojure.lang.PersistentArrayMap

在 Clojure 中,括号很重要:你不能添加额外的括号,也不能省略它们——它们需要放在正确的位置。

当你拥有它时,它将作为一个函数调用。当你有 时,它将评估以生成一个哈希映射,然后将该哈希映射作为没有参数的函数调用,这就是导致该错误的原因。(expr)expr((assoc ...))(assoc ...)

你遇到的另一个问题 - 对于从其他语言来到 Clojure 的人来说很常见 - 是数据是不可变的,所以不会修改,它返回一个新的哈希映射,并添加了额外的条目。因为你拥有它,所以有效地抛弃了这个新值,并用剩余值再次循环。assocgrid:cells(do (assoc ...) (recur ...))

除了元素之外,你的 / 还需要保留累积值,然后有一个 so 你在为空时返回累积值。looprecurremainingifremaining

这可能也是错误的,因为它将尝试使用单个参数调用(值)作为函数。也许你的意思是哪一对将是具有 和 值的对?(x y)xy[x y]xy

评论

0赞 Braden Christopher 10/12/2023
谢谢,这听起来真的很好。我会尝试这个,如果我有问题,我会回来!