问题描述
我是 Scheme 编程的初学者.我知道 Scheme 中的点表示法是用来表示一对符号的,例如 '(a . b)
.
第一个元素可以是一个符号,也可以是一个列表,这无关紧要.但是特别是第二个元素必须是一个符号,如果不是,例如可能是一个列表,那么我们就不能用内置的cons
过程创建一对.
那么是否可以创建一对 2 列表???嗯,我正在考虑一个解决方案是将列表转换为符号,但实际上它们是两个完全不同的东西 -> 据我所知是不可能的.
这是我写的代码:
(定义比较属性(lambda (attribute1 attribute2)(if (or (and (null? attribute1) (null? attribute2)) (and (not (null? attribute1)) (not (null? attribute2))))(缺点attribute1attribute2)#F)))
其中attribute1和attribute2是2个列表,我的输出是:
attribute1 atrtribute2
预期输出:'(attribute1 .attribute2)
请解释一下.提前致谢!!!
添加 compare-attrs 函数的使用
compare-attrs 函数用来提取描述实体属性的部分,并将它们cons
配对,实体定义如下:
(entity e0 (prov:label "entity e0")(实体 e1 (prov:location "London")
所以这些实体的属性是(prov:label "entity e0")
和 (prov:location "London")
.当应用compare-attrs函数时,因为这些属性不是null
,所以我期望的输出是
`(prov:label "entity e0") .(prov:location "London")`
注意:这是从对 递归的回答中提取的Lisp 中的范围添加了句点?,这实际上是在问一个不同的问题.但是,对如何打印的解释是相同的.其余的答案是不同的.
你的问题有点误解,但我想我们可以澄清一下.
第一个 [argument to cons
] 可以是一个符号或一个列表,它没关系.但特别是第二个元素必须是一个符号,如果它不是,例如可能是一个列表,那么我们不能创建一个对带有内置的 cons 程序.
这是不正确的.你可以用你喜欢的任何参数调用 cons
,你会总是得到一个 cons
单元,它的 car
是与 cons
的第一个参数相同,并且其 cdr
与 cons
的第二个参数相同.也就是说,cons
唯一重要的是它满足方程
(eq? a (car (cons a b))(eq? b (cdr (cons a b))
那么是否可以创建一对 2 列表???嗯,我在想一个解决方案是将列表转换为符号,但实际上它们是2 件完全不同的事情 -> 据我所知是不可能的.
很有可能;如果您有两个列表,例如 list1
和 list2
,您可以创建一对 car
是 list1
和其 cdr
是 list2
只需调用 (cons list1 list2)
.现在,我认为您遇到的问题是您希望看到 ( . )
作为输出,你会看到一些不同的东西.为了解释为什么会这样,我们需要了解列表在 Lisps 中是如何表示的,以及对是如何打印的.
Scheme 中的列表要么是空列表 ()
(在某些 Lisps 中也称为 nil
),要么是一个其 car
(也称为first
)是列表的一个元素,其cdr
(也称为rest
)是列表的其余部分(即另一个列表),或终止列表的原子.常规的终止符是空列表()
;由 ()
终止的列表被称为适当的列表".由任何其他原子终止的列表称为不正确的列表".列表 (1 2 3 4 5)
包含元素 1、2、3、4 和 5,并以 ()
结束.你可以通过
(cons 1 (cons 2 (cons 3 (cons 4 (cons 5 ())))))
现在,当系统打印一个cons单元格时,一般情况是通过
打印它(车.cdr)
例如(cons 1 2)
的结果打印为
(1 . 2)
由于列表是由 cons 单元构成的,因此您也可以将这种表示法用于列表:
'(1 2 3 4 5) =='(1 . (2 . (3 . (4 . (5 . ())))))
不过,这有点笨拙,所以大多数 lisps(我所知道的)都有一个特殊的情况来打印 cons 单元格:如果 cdr
是一个列表(另一个 cons 单元格,或 ()
),然后不打印 .
,也不要打印 cdr
周围的括号(否则它会有,因为这是一个列表).
现在我们可以解释为什么 (cons list1 list2)
的结果看起来不像 ( . )代码>.如果你用两个列表调用
cons
,你do 会得到一对预期的 car
和 cdr
,但是它不是用 .
符号打印的.例如,
(cons '(1 2 3) '(a b c));=>((1 2 3) . (a b c)) ;通常*打印*为;=>((1 2 3) a b c)
但同样,打印的表示并不重要,只要以下等式成立:
(eq? a (car (cons a b))(eq? b (cdr (cons a b))
果然:
(car (cons '(1 2 3) '(a b c)));=>(1 2 3)(cdr (cons '(1 2 3) '(a b c)));=>(a b c)
在您询问的具体示例中,请考虑调用时会发生什么
(cons '(prov:label "entity e0") '(prov:location "London"))
结果是,事实上,
((prov:label "entity e0") . (prov:location "London"))
但是,由于打印规则,这打印为
((prov:label "entity e0") prov:location "London")
尽管如此,您仍然可以通过使用car
和cdr
来获取这两个属性:
(car '((prov:label "entity e0") prov:location "London"));=>(证明:标签实体 e0")(cdr '((prov:label "entity e0") prov:location "London"));=>(prov:位置伦敦")
这就是您以后真正需要做的事情.
I'm a beginner in Scheme programming. I know that the dot notation in Scheme is used to present a pair of symbol, for example '(a . b)
.
The first element could be a symbol, or a list, it doesn't matter. But specially the second element must be a symbol, if it is not, may be a list for instance, then we can't create a pair with built-in cons
procedure.
So is it possible to create a pair of 2 lists??? Well i'm thinking of a solution is that converting a list to symbol but actually those are 2 completely different thing -> impossible as i understand.
This is the code i wrote:
(define compare-attrs
(lambda (attribute1 attribute2)
(if (or (and (null? attribute1) (null? attribute2)) (and (not (null? attribute1)) (not (null? attribute2))))
(cons attribute1 attribute2)
#f)))
In which attribute1 and attribute2 is 2 lists, and my output is:
attribute1 atrribute2
Expected output: '(attribute1 . attribute2)
Please explain this. Thank in advance!!!
EDIT: adding the use of compare-attrs function
The function compare-attrs used to extract the part that describes attributes of entities and cons
them to make a pair, entities defined defined below:
(entity e0 (prov:label "entity e0")
(entity e1 (prov:location "London")
so attribute of these entities are (prov:label "entity e0")
and (prov:location "London")
.When apply the function compare-attrs, because these attributes are not null
, so that the output i expect is
`(prov:label "entity e0") . (prov:location "London")`
Note: this is cannibalized from an answer to Recursive range in Lisp adds a period?, which is really asking a different question. However, the explanation of how pairs are printed is the same. The rest of the answer is different.
Your question exhibits a bit of misunderstanding, but I think we can clear it up.
This is not correct. You can call cons
with whatever arguments you like, and you will always get back a cons
cell whose car
is the same as the first argument to cons
, and whose cdr
is the same as the second argument to cons
. That is, the only thing that's important about cons
is that it satisfies the equations
(eq? a (car (cons a b))
(eq? b (cdr (cons a b))
It's quite possible; if you have two lists, e.g., list1
and list2
, you can create a pair whose car
is list1
and whose cdr
is list2
just by calling (cons list1 list2)
. Now, I think the issue that you're running up against is that you're expecting to see (<value-of-list1> . <value-of-list2>)
as the output, and you're seeing some different. To explain why this is, we need to understand how lists are represented in Lisps, and how pairs are printed.
A list in Scheme is either the empty list ()
(also known as nil
in some Lisps), or a cons cell whose car
(also known as first
) is an element of the list and whose cdr
(also known as rest
) is either the rest of the list (i.e., another list), or an atom that terminates the list. The conventional terminator is the empty list ()
; lists terminated by ()
are said to be "proper lists". Lists terminated by any other atom are called "improper lists". The list (1 2 3 4 5)
contains the elements 1, 2, 3, 4, and 5, and is terminated by ()
. You could construct it by
(cons 1 (cons 2 (cons 3 (cons 4 (cons 5 ())))))
Now, when the system prints a cons cell, the general case is to print it by
(car . cdr)
For instance, the result of (cons 1 2)
is printed as
(1 . 2)
Since lists are built of cons cells, you can use this notation for lists too:
'(1 2 3 4 5) ==
'(1 . (2 . (3 . (4 . (5 . ())))))
That's rather clunky, though, so most lisps (all that I know of) have a special case for printing cons cells: if the cdr
is a list (either another cons cell, or ()
), then don't print the .
, and don't print the surrounding parenthesis of the cdr
(which it would otherwise have, since it's a list).
Now we can explain why the result of (cons list1 list2)
doesn't look like (<value-of-list1> . <value-of-list2>)
. If you call cons
with two lists, you do get back a pair with the expected car
and cdr
, but it's not printed with the .
notation. E.g.,
(cons '(1 2 3) '(a b c))
;=> ((1 2 3) . (a b c)) ; which is typically *printed* as
;=> ((1 2 3) a b c)
But again, the printed representation doesn't really matter though, as long as the following equations hold:
(eq? a (car (cons a b))
(eq? b (cdr (cons a b))
Sure enough:
(car (cons '(1 2 3) '(a b c)))
;=> (1 2 3)
(cdr (cons '(1 2 3) '(a b c)))
;=> (a b c)
In the specific example you're asking about, consider what happens when you call
(cons '(prov:label "entity e0") '(prov:location "London"))
The result is, in fact,
((prov:label "entity e0") . (prov:location "London"))
but, because of the printing rules, this is printed as
((prov:label "entity e0") prov:location "London")
Nonetheless, you can still get the two attributes out by using car
and cdr
:
(car '((prov:label "entity e0") prov:location "London"))
;=> (prov:label "entity e0")
(cdr '((prov:label "entity e0") prov:location "London"))
;=> (prov:location "London")
and that's all you really need to be able to do later.
这篇关于方案中的点符号的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!