将clojure函数求值为引号形式



我使用的函数接受如下参数:(test-function '((gate 1) (gate 3) (gate 2)))

list参数可以包含任意数量的元素,其中每个元素的形式为(gate x),其中x可以是0到8之间的整数。我有一个函数generate-gate-list,它生成随机长度(最多10)和内容的列表,尽管它们总是上述形式。

generate-gate-list输出示例:((gate 2)), (()), ((gate 1) (gate 6))

我希望能够在test-function内嵌套generate-gate-list,以便我可以测试一堆随机生成的列表,而无需事先生成它们。换句话说,我想要这样的东西:(test-function '(generate-gate-list)),除了generate-gate-list已经被评估。我已经尝试了一些宏语法-引用和取消引用,但这会导致解析变量,如(user/gate 3),它搞糟了test-function。下面是我的生成门列表代码:

(defn generate-gate-list []
  (map symbol (repeatedly (rand-int 10) #(random-gate))))

random-gate输出一个门元素作为字符串,即"(gate 3)""(gate 2)"

所以简而言之,我希望(test-function (something-here (generate-gate-list)))(test-function (modified-generate-gate-list))等同于(test-function '((gate 1) (gate 4) (gate 2)))或generate-gate-list的其他任意输出。谢谢!

引用生成文字列表

我相信你的困惑是认为报价是产生清单的唯一方法。正如您可能已经发现的那样,虽然引用可以像'((gate 1) (gate 2))那样生成一个文字列表,但列表中没有任何内容被求值。因此,您不能以这种方式生成随机列表,因为您的随机变量将不会被求值。

符号只产生符号

在列表"(门1)"的文本表示上调用symbol,正如您在generate-gate-list函数中所做的那样,不起作用。它产生的符号看起来像一个列表,而不是一个列表。

user=> (type (symbol "(gate 1)"))
clojure.lang.Symbol

使用list

创建列表

如果你想求值,即用变量填充你的列表,使用list函数。

user=> (list 'gate 1)
(gate 1)
user=> (list 'gate (rand-int 10))
(gate 2)

不知道你的test-function是什么,让我们这样做

(defn test-function 
  [gate-list]
  "Turn a list of (gate n) pairs into a list of gate numbers" 
  (map second gate-list))

user=> (test-function '((gate 1) (gate 2)))
(1 2)

(defn generate-gate-list []
  (repeatedly (rand-int 10) #(list 'gate (rand-int 10))))
user=> (def a-random-list (generate-gate-list))
#'user/a-random-list
user=> a-random-list
((gate 2) (gate 5) (gate 2) (gate 8) (gate 4))
user=> (test-function a-random-list)
(2 5 2 8 4)

最新更新