我是Scheme编程的初学者.我知道Scheme中的点符号用于表示一对符号,例如'(a . b).
第一个元素可以是符号,也可以是列表,无关紧要.但特别是第二个元素必须是一个符号,如果不是,可能是一个列表,那么我们就不能创建一个内置cons过程的对.
那么有可能创建一对2列表??? 好吧,我正在考虑一个解决方案是将列表转换为符号,但实际上这些是完全不同的两件事 - >根据我的理解不可能.
这是我写的代码:
(define compare-attrs
(lambda (attribute1 attribute2)
(if (or (and (null? attribute1) (null? attribute2)) (and (not (null? attribute1)) (not (null? attribute2))))
(cons attribute1 attribute2)
#f)))
Run Code Online (Sandbox Code Playgroud)
其中attribute1和attribute2是2个列表,我的输出是:
attribute1 atrribute2
Run Code Online (Sandbox Code Playgroud)
预期输出:'(attribute1.attribute2)
请解释一下.预先感谢!!!
编辑:添加比较attrs功能的使用
函数compare-attrs用于提取描述实体属性的部分,并将cons它们组成一对,实体定义如下:
(entity e0 (prov:label "entity e0")
(entity e1 (prov:location "London")
Run Code Online (Sandbox Code Playgroud)
所以这些实体的属性是(prov:label "entity e0")和(prov:location "London").当应用函数compare-attrs时,因为这些属性不是null,所以我期望的输出是
`(prov:label "entity e0") . (prov:location "London")`
Run Code Online (Sandbox Code Playgroud)
Jos*_*lor 13
注意:这是从Lisp的递归范围的答案中蚕食增加了一段时间?,这真的是在问一个不同的问题.但是,如何打印对的说明是相同的.其余的答案是不同的.
你的问题表现出一些误解,但我认为我们可以解决它.
第一个[参数
cons]可以是符号或列表,也无关紧要.但特别是第二个元素必须是一个符号,如果不是,可能是一个列表,那么我们就不能创建一个内置的cons过程.
这是不正确的.您可以cons使用您喜欢的任何参数调用,并且您将始终返回与第一个参数相同的cons单元格,并且与第二个参数相同.也就是说,唯一重要的是它满足方程式carconscdrconscons
(eq? a (car (cons a b))
(eq? b (cdr (cons a b))
Run Code Online (Sandbox Code Playgroud)
那么有可能创建一对2列表??? 好吧,我正在考虑一个解决方案是将列表转换为符号,但实际上这些是完全不同的两件事 - >根据我的理解不可能.
这很可能; 如果你有两个列表,例如,list1和list2,你可以创建一个对谁car是list1,其cdr是list2刚刚通过调用(cons list1 list2).现在,我认为你遇到的问题是你期望看到 (<value-of-list1> . <value-of-list2>)输出,你会看到一些不同的东西.为了解释这是为什么,我们需要了解如何在Lisps中表示列表,以及如何打印对.
方案A列表要么是空列表()(也称为nil在一些的Lisp)或cons单元,其car(也称为first)是与所述列表的一个元件,其cdr(也称为rest)或者是列表的其余部分(即,另一个列表),或终止列表的原子.传统的终结符是空列表(); 被终止的名单()被称为"适当的名单".被任何其他原子终止的列表称为"不正确的列表".该列表(1 2 3 4 5)包含元素1,2,3,4和5,并以().你可以通过构建它
(cons 1 (cons 2 (cons 3 (cons 4 (cons 5 ())))))
Run Code Online (Sandbox Code Playgroud)
现在,当系统打印 cons单元格时,一般情况是打印它
(car . cdr)
Run Code Online (Sandbox Code Playgroud)
例如,结果(cons 1 2)打印为
(1 . 2)
Run Code Online (Sandbox Code Playgroud)
由于列表是由cons单元格构建的,因此您也可以将此表示法用于列表:
'(1 2 3 4 5) ==
'(1 . (2 . (3 . (4 . (5 . ())))))
Run Code Online (Sandbox Code Playgroud)
但是,这是相当笨重的,所以大多数lisps(我所知道的)都有一个打印cons单元格的特殊情况:如果cdr是一个列表(或者是另一个cons单元格,或者()),那么就不要打印.,而不是打印周围的括号cdr(否则它将具有,因为它是一个列表).
现在我们可以解释为什么结果(cons list1 list2)看起来不像(<value-of-list1> . <value-of-list2>).如果调用cons与两个列表,你就回来与预期的一对car和cdr,但它不是印有.符号.例如,
(cons '(1 2 3) '(a b c))
;=> ((1 2 3) . (a b c)) ; which is typically *printed* as
;=> ((1 2 3) a b c)
Run Code Online (Sandbox Code Playgroud)
但同样,印刷表示并不重要,只要以下等式成立:
(eq? a (car (cons a b))
(eq? b (cdr (cons a b))
Run Code Online (Sandbox Code Playgroud)
果然:
(car (cons '(1 2 3) '(a b c)))
;=> (1 2 3)
(cdr (cons '(1 2 3) '(a b c)))
;=> (a b c)
Run Code Online (Sandbox Code Playgroud)
在你问的具体例子中,考虑一下你打电话时会发生什么
(cons '(prov:label "entity e0") '(prov:location "London"))
Run Code Online (Sandbox Code Playgroud)
结果实际上是
((prov:label "entity e0") . (prov:location "London"))
Run Code Online (Sandbox Code Playgroud)
但是,由于打印规则,打印为
((prov:label "entity e0") prov:location "London")
Run Code Online (Sandbox Code Playgroud)
尽管如此,您仍然可以通过使用car和获取这两个属性cdr:
(car '((prov:label "entity e0") prov:location "London"))
;=> (prov:label "entity e0")
(cdr '((prov:label "entity e0") prov:location "London"))
;=> (prov:location "London")
Run Code Online (Sandbox Code Playgroud)
这就是你以后真正需要做的所有事情.
Scheme中的点符号或任何其他LISP方言用于创建任意两个值的点对.值可以是符号,列表或其他任何值.它的价值无关紧要.例如:
'(author . aaditmshah) => (author . aaditmshah)
'((a b c) . (d e f)) => ((a b c) d e f)
Run Code Online (Sandbox Code Playgroud)
如您所见,如果您创建一对两个列表的点对,则第一个列表将添加到第二个列表的头部.这是因为LISP中的列表是嵌套的点对:
'(a . (b . (c . ()))) => '(a b c)
Run Code Online (Sandbox Code Playgroud)
因此,当您编写'((a b c) . (d e f))它时,就好像您正在编写以下内容:
'((a b c) . (d . (e . (f . ())))) => '((a b c) d e f)
Run Code Online (Sandbox Code Playgroud)
这完全有效.您仍然可以使用car和cdr正常访问这两个列表:
(car '((a b c) . (d e f))) => (a b c)
(cdr '((a b c) . (d e f))) => (d e f)
Run Code Online (Sandbox Code Playgroud)
我不确定你的compare-attrs功能应该做什么.您的if分支返回一个cons单元格,而您的else分支返回一个布尔值.对我来说,这绝对没有意义.函数的返回类型应该是常量.
也许你没有正确地提出你的问题,因为我不确定你的问题是什么.如果你还有任何疑问,请告诉我.
| 归档时间: |
|
| 查看次数: |
6056 次 |
| 最近记录: |