- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我知道你可以使用 '
(又名 quote
)来创建一个列表,我一直使用它,就像这样:
> (car '(1 2 3))
1
> (define math-fns '(+ - * /))
> (map (lambda (fn) (fn 1)) math-fns)
application: not a procedure;
expected a procedure that can be applied to arguments
given: '+
list
时,它可以工作:
> (define math-fns (list + - * /))
> (map (lambda (fn) (fn 1)) math-fns)
'(1 -1 1 1)
'
只是一个方便的速记,那么为什么行为不同呢?
最佳答案
TL;DR:他们是不同的;如有疑问,请使用 list
。
经验法则:每当您想要评估参数时,请使用 list
; quote
“分布”在它的参数上,所以 '(+ 1 2)
就像 (list '+ '1 '2)
。您最终会在列表中得到一个符号,而不是一个函数。
深入了解 list
和 quote
在 Scheme 和 Racket 中,quote
和 list
是完全不同的东西,但是由于它们都可以用于生成列表,因此混淆是常见且可以理解的。它们之间有一个非常重要的区别:list
是一个普通的老功能,而quote
(即使没有特殊'
语法)是一个特殊形式。即 list
可以在普通 Scheme 中实现,但 quote
不能。list
函数list
函数实际上是两者中最简单的一个,所以让我们从那里开始。它是一个接受任意数量参数的函数,并将参数收集到一个列表中。
> (list 1 2 3)
(1 2 3)
quote
的 s 表达式,这是真的,在这种情况下,两种语法是等效的。但是如果我们稍微复杂一点,你会发现它是不同的:
> (list 1 (+ 1 1) (+ 1 1 1))
(1 2 3)
> '(1 (+ 1 1) (+ 1 1 1))
(1 (+ 1 1) (+ 1 1 1))
quote
示例中发生了什么?好吧,我们稍后会讨论这个,但首先,看看
list
。它只是一个普通的函数,所以它遵循标准的 Scheme 评估语义:它在每个参数传递给函数之前评估它的每个参数。这意味着像
(+ 1 1)
这样的表达式在它们被收集到列表中之前将减少到
2
。
> (define x 42)
> (list x)
(42)
> '(x)
(x)
list
,
x
在传递给
list
之前被评估。使用
quote
,事情变得更加复杂。
list
只是一个函数,所以它可以像任何其他函数一样使用,包括以更高阶的方式使用。例如,它可以传递给
map
函数,它会正常工作:
> (map list '(1 2 3) '(4 5 6))
((1 4) (2 5) (3 6))
quote
形式
list
不同,引用是 Lisps 的一个特殊部分。
quote
形式的特殊部分是因为它有一个特殊的读取器缩写
'
,但即使没有它,它也很特殊。与
list
不同,
quote
不是函数,因此它不需要表现得像一个函数——它有自己的规则。
(+ 1 2)
+
符号 1
2
1
值真的很容易,因为它会计算自身:您只需键入
1
。但是符号和列表更难:默认情况下,源代码中的符号会执行变量查找!也就是说,符号不是自我评估的:
> 1
1
> a
a: undefined
cannot reference undefined identifier
> (string->symbol "a")
a
(+ 1 2)
查看列表中的第一个元素,即
+
符号,查找与其关联的函数,并使用列表中的其余元素调用它。
quote
。
quote
做了什么:它只是“关闭”了它包装的表达式的特殊评估行为。例如,考虑
quote
一个符号:
> (quote a)
a
quote
列表:
> (quote (a b c))
(a b c)
quote
,它总是会,
总是 吐出来给你。不多也不少。这意味着如果你给它一个列表,任何子表达式都不会被计算——不要指望它们会被计算!如果您需要任何类型的评估,请使用
list
。
quote
不是符号或列表,会发生什么?嗯,答案是……没什么!你只要把它拿回来。
> (quote 1)
1
> (quote "abcd")
"abcd"
quote
仍然只是准确地吐出你给它的东西。这就是为什么像数字和字符串这样的“文字”有时在 Lisp 的说法中被称为“自引用”。
quote
一个包含
quote
的表达式会发生什么?也就是说,如果你“双
quote
”呢?
> (quote (quote 3))
'3
'
实际上只是
quote
的直接缩写,所以根本没有发生什么特别的事情!事实上,如果你的 Scheme 有办法在打印时禁用缩写,它会是这样的:
> (quote (quote 3))
(quote 3)
quote
的特殊性所迷惑:就像
(quote (+ 1))
一样,这里的结果只是一个普通的旧列表。事实上,我们可以从列表中取出第一个元素:你能猜出它是什么吗?
> (car (quote (quote 3)))
quote
3
,那你就错了。请记住,
quote
禁用所有评估,并且包含
quote
符号的表达式仍然只是一个简单的列表。在 REPL 中使用它,直到您对它感到满意为止。
> (quote (quote (quote 3)))
''3
(quote (1 2 (quote 3)))
(1 2 '3)
quote
,而是使用
quasiquote
。通常,这在各方面都与
quote
完全一样:
> (quasiquote 3)
3
> (quasiquote x)
x
> (quasiquote ((a b) (c d)))
((a b) (c d))
quasiquote
特殊的是它识别特殊符号
unquote
。只要
unquote
出现在列表中,就会被它包含的任意表达式替换:
> (quasiquote (1 2 (+ 1 2)))
(1 2 (+ 1 2))
> (quasiquote (1 2 (unquote (+ 1 2))))
(1 2 3)
quasiquote
来构建具有“漏洞”的各种模板,这些模板将用
unquote
填充。这意味着可以在引用列表中实际包含变量的值:
> (define x 42)
> (quasiquote (x is: (unquote x)))
(x is: 42)
quasiquote
和
unquote
比较冗长,所以它们都有自己的缩写,就像
'
一样。具体来说,
quasiquote
是
`
(反引号),
unquote
是
,
(逗号)。有了这些缩写,上面的例子就更可口了。
> `(x is: ,x)
(x is: 42)
list
、
cons
,当然还有
quote
的用法。
list
和
quote
list
非常简单,因为“rest 参数”语法是如何工作的。这就是你所需要的:
(define (list . args)
args)
quote
要困难得多——事实上,这是不可能的!这似乎是完全可行的,因为禁用评估的想法听起来很像宏。然而一个天真的尝试暴露了问题:
(define fake-quote
(syntax-rules ()
((_ arg) arg)))
arg
并把它吐出来……但这不起作用。为什么不?好吧,我们的宏的结果将被评估,所以一切都是徒劳的。通过扩展到
quote
并递归引用元素,我们可以扩展到类似于
(list ...)
的东西,如下所示:
(define impostor-quote
(syntax-rules ()
((_ (a . b)) (cons (impostor-quote a) (impostor-quote b)))
((_ (e ...)) (list (impostor-quote e) ...))
((_ x) x)))
quote
的符号。我们可以使用
syntax-case
接近,但即便如此,我们也只会模拟
quote
的行为,而不是复制它。
'
,例如在此示例中:
> (list 1 2 3)
'(1 2 3)
(print-as-expression #f)
,或在 DrRacket 语言菜单中将打印样式更改为“写入”。
关于scheme - 报价单和列表有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34984552/
如标题所示,ans_list是一个答案列表,ans_index是一个数字(答案在词汇表中的索引,但与atm无关) 这里生成的 tree.anslist 是什么? (例如,仅针对第一个),忽略迭代。 f
我目前将用户的输入存储在逗号分隔的列表中,如下所示: Userid | Options 1 | 1,2,5 用户在一个数组形式中勾选一组选项,然后用逗号连接起来 1,2,5 然后 MySQ
我目前将用户的输入存储在逗号分隔的列表中,如下所示: Userid | Options 1 | 1,2,5 用户在一个数组形式中勾选一组选项,然后用逗号连接起来 1,2,5 然后 MySQ
我想知道如何完全展平列表和包含它们的东西。除其他外,我想出了一个解决方案,它可以将具有多个元素的东西滑倒并将它们放回原处,或者在滑倒后将具有一个元素的东西拿走。 这与 How do I “flatte
我想知道如何完全展平列表和包含它们的东西。除其他外,我想出了一个解决方案,它可以将具有多个元素的东西滑倒并将它们放回原处,或者在滑倒后将带有一个元素的东西拿走。 这与 How do I “flatte
这个问题已经有答案了: Convert nested list to 2d array (3 个回答) 已关闭 7 年前。 java中有没有快捷方式可以转换 List> 到 String[][] ?
我在排序时遇到问题 List> 。我创建了一个自定义比较器,在其中编写了对数据进行排序的代码。 public class CustomComparator implements Comparator
这个问题已经有答案了: 已关闭10 年前。 Possible Duplicate: Java Generics: Cannot cast List to List? 我只是想知道为什么下面的java代
试图想出一个 LINQy 方法来做到这一点,但我什么也没想到。 我有一个对象列表<>,其中包含一个属性,该属性是逗号分隔的字母代码列表: lst[0].codes = "AA,BB,DD" lst[1
假设我有这些任务: points = [] point = (1, 2) 我怎么会这样做: points += point 它工作得很好,并且给了我点 = [1, 2]。但是,如果我这样做: poin
如何在 scala 中将 List[Task[List[Header]]] 类型转换为 Task[List[Header]]。 我有一个方法返回 Task[List[Header]] 并多次调用 do
如何在 Java 中查找二维列表的元素? 我有一个参数为 List> 的函数我想知道如何找到这个列表的行和列。 最佳答案 如果你喜欢 List> obj 然后你就可以像这样访问 obj.get(cur
分配 List到 List工作正常。 分配 List>到 List>不编译。 代码 public class Main { public static void main(String[] a
我正在用 Java 编写一个方法,该方法必须接收并迭代 Serializable 的 List。 有什么区别: public void myMethod(List list) { } 和 public
我看到很多人想用 mvvm 更新网格/列表/树的一部分,但他们不想刷新整个列表。 对于所有遇到此问题的人,我做了以下示例。 希望这对你有用。 最佳答案 这是一个简单的例子。整个代码中最重要的是: Bi
我正在为现有的 C++ 库编写包装器,该库使用列表,其中 T 是自定义结构。我被建议使用 vector 而不是列表,但我试图避免修改库。 为了更好地理解这个场景,我做了一个简单的应用程序,使用一个列表
List list List list 这两种声明有什么区别吗? 谢谢, 最佳答案 是的。 List可以包含所有派生自 Base 的不同事物的混合物. List包含同质项(从某种意义上说,它们必须全部
有人可以尽可能详细地解释以下类型之间的区别吗? List List List 让我更具体一点。我什么时候想使用 // 1 public void CanYouGiveMeAnAnswer(List l
我有一个元组列表,每个元组都是一对列表。所以我的数据看起来像: mylist = [(['foo', 'bar'], ['bar', 'bar']),(['bar', 'bar'],['bar', '
也许是一个时髦的标题,但我遇到了以下问题: 给定一个类型为 (a * b) list 的列表,我想创建一个类型为 (a * b list) list 的新列表。一个例子: 给定列表 let testL
我是一名优秀的程序员,十分优秀!