【问题标题】:What is the concept of "third" in Primitive function scheme?原始函数方案中的“第三”是什么概念?
【发布时间】:2021-06-09 04:50:27
【问题描述】:

我是方案计算的新手。

我有一个给定的问题:

(DEFINE (第三个C) (CAR(CDR CDR(C))))

(第三个'(A (B C) (D E) F))

我知道CDR和CAR的概念,但我不明白“第三”会做什么。我读到这是定义“三人组???”的一种方式。

我倾向于将 C 的值替换为第三个语句旁边的第二个语句的值,即‘(A (B C) (D E) F),这是正确的吗?

你能用简单的术语解释一下“第三”在这个给定的情况下做了什么,我该如何解决这个给定的问题?

【问题讨论】:

  • 嗯,它返回列表的第三个元素......你没有尝试过吗?
  • 虽然third 的实现是无效的,但是内置在racket 等方案实现或SRFI-1 等库中的实现将起作用。它只是caddr 的别名,更易于阅读。
  • 我们有解决方案吗?这是我的 MS 研究的主题之一。我们的教授只是想我们理论以及 CDR 和 CAR 和 CONS 是如何工作的。我在哪里可以测试这个?
  • 下载任何 Scheme 解释器并自己尝试(例如 Racket)。仅仅通过阅读理论,你将如何学习?开始编写一些代码,测试它,看看它运行!

标签: scheme primitive


【解决方案1】:

在 lisps 中,列表是一种基本的数据结构,它由对组成。传统上,该对的第一个成员称为它的 car,第二个成员称为它的 cdr:

(汽车.cdr)

这里的点表示该对由两个单元格组成。给定一对(a . b),第一个成员的访问器也称为car,第二个成员的访问器称为cdr。所以:

(car '(a . b)) --> a 和
(cdr '(a . b)) --> b。

为了形成一个列表,对的组合方式如下:第一对的第一个成员是列表的第一个元素,第一对的第二个成员要么是空列表,要么是代表其余元素的对的名单。因此,一个元素的列表,例如 (a) 由一对 (a . ()) 表示。

两个元素的列表,例如,(a b) 由 (a . (b . ())) 对表示。这里,第一对的第二个成员是(b . ())。您会注意到列表(a b) 的cdr 是列表(b),或等效为(b . ())。

三个元素的列表,例如 (a b c) 类似地表示为 (a . (b . (c . ())))。列表是具有空列表() 或其cdr 中的一对的对。这里有一个关于正确列表的区别(最后一对必须在其cdr 中有一个())和不正确的列表,但我将在这里忽略这种区别。并且空列表也是一个列表(但不是一对)。更准确地说:在 Scheme 中,列表要么是空列表,要么是 cdr 为列表的对。

所以,car 获取列表的第一个成员,cdr 获取列表的其余部分。鉴于列表(a b c d),我们可以看到:

(cdr '(a b c d)) --> (b c d), 和
(cdr (cdr '(a b c d))) --> (cdr '(b c d)) --> (c d), 和
(car (cdr (cdr '(a b c d)))) --> (car (cdr '(b c d))) --> @ 987654353@ --> c.

所以,给定定义:

(define (third xs)
  (car (cdr (cdr xs))))

我们有:

> (third '(a b c d))
c

我将把它留给 OP 将此信息应用于以下问题:

(third '(a (b c) (d e) f)) --> ?

【讨论】:

  • 非常感谢!!!!我想知道 QUOTE 是否像给定的(DEFINE (third C) (CAR(CDR CDR(C)))) 一样重要,我的教授没有给出 C 的值。所以,我们假设值只是 C。我可以说 cdr(C) = cdr(C . ()) 即使没有 QUOTE '
  • @GieGrajo -- 引用不是列表的一部分;它是quote 的简写,它不是一个函数,但通常称为特殊形式。函数调用在 lisps 中用括号表示,因此 (third '(a b c)) 表示使用参数 (a b c) 调用函数 third。但是,函数总是在 lisps 中评估它们的参数,所以不带引号的 (third (a b c)) 会尝试评估 (a b c),这是一个尝试调用函数 @ 的 函数调用 987654365@ 带有参数 b 和 c。引用 suppresses evaluation....
  • 所以,'(a b c) 计算结果为列表 (a b c),但 (a b c) 计算结果为函数调用。正如我所说,单引号是quote 的简写,因此您也可以使用(quote (a b c)),其计算结果为列表(a b c),即(third (quote (a b c)))。
  • 现在,你有cdr(C) = cdr(C . ()),还有(CAR (CDR CDR(C)))。括号在这里不合适;请记住,括号表示 lisps 中的函数调用(某些特殊情况除外)。您需要(cdr C) 才能获得C 的cdr。但是(cdr '(C . ())) 是(),所以不是=。而且,您需要(CAR (CDR (CDR C))) 而不是(CAR (CDR CDR(C)))。
  • 但是,在函数定义中你不想引用C,因为它是函数的参数,将由参数填充 当函数被调用时。请注意,在我的回答中,我在third 的定义中使用了xs 而不是C。没有特别的原因,除了我通常将xs 用于通用列表(其中包含一堆元素x)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-02-04
  • 1970-01-01
  • 2010-11-24
  • 2012-10-04
  • 2011-04-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多