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

问题描述 投票:0回答:1

我正在尝试将嵌套向量添加到地图中,即({:cells {[x y]})。我尝试过多种方式来做到这一点,但无论我如何尝试,我都无法让它发挥作用。我不断收到“错误数量的参数(0)传递给:clojure.lang.PercientArrayMap”,或者在另一种情况下,我什至无法获得剩余的函数,即(坐标生成)来编译它。我必须手动重新输入它们才能让 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
1个回答
0
投票

由于您发布的代码无法编译 - 它会生成

Syntax error: Can only recur from tail position
- 我假设您的意思是
(do
而不是
do(

修复该问题不会产生您所看到的错误,但我怀疑

((assoc grid :cells (x y)))
会导致
Wrong number of args (0) passed to: clojure.lang.PersistentArrayMap

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

当你有

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

您遇到的另一个问题(对于从其他语言转向 Clojure 的人来说很常见)是数据是不可变的,因此

assoc
不会修改
grid
,它会返回一个带有附加
 的新哈希映射添加了:cells
条目。因为你有
(do (assoc ...) (recur ...))
,它可以有效地消除新值并再次循环剩余值。

您的

loop
/
recur
除了
remaining
元素之外还需要保留累积值,然后有一个
if
,以便在
remaining
为空时返回累积值。

那个

(x y)
也可能是错误的,因为它会尝试将
x
(的值)作为具有单个参数
y
的函数来调用。也许您的意思是
[x y]
这将是一对,其中包含
x
y
的值?

© www.soinside.com 2019 - 2024. All rights reserved.