gpt4 book ai didi

struct - 如何在方案中实现Racket风格的结构?

转载 作者:行者123 更新时间:2023-12-02 08:06:48 24 4
gpt4 key购买 nike

在 Racket 中,您有机会创建和使用这样的结构类型

(define-struct example (a b))

(define var (make-example 1 2))

(example? var)

(example-a var)

我正在尝试使用宏在方案中实现类似的东西,但我在创建具有组合名称的过程时遇到问题,例如 (make-example 1 2) 其中而不是 example 绝对可以是任何东西。有没有办法用这样的名称定义过程或其他方法来解决这个问题?

最佳答案

Scheme有必要实现吗?

无需寻找其他语言中已有的功能。它只是有一个不同的名称:记录!

它在 SRFI-9 Defining record types 中定义最新的 R7RS 包含对此的向后兼容性,因此即使在 R5RS 中也可以选择此功能。许多 R5RS 实现都包含它们。 R6RS 有不同的记录实现,不兼容,此时应避免。

#!r6rs
;; You want to use SRFI-9 rather than the d\included define-record-type
(import (except (rnrs) define-record-type)
(srfi :9))

(define-record-type :example
(make-example a b)
example?
(a example-a set-example-a!)
(b example-b set-example-b!))

(define var (make-example 1 2))
(example? var) ; ==> #t
(example-a var) ; ==> 1

无论如何你都想尝试一下以获取学习和乐趣

那么最好的方法就是尝试自己解决这个问题。要创建一个用于连接标识符的宏,您不能使用define-syntax,因为它无法做到这一点。在不做太多作弊的情况下这样做会让你更好地理解宏。在 R6RS 中,syntax-case 位于包含的库中,您可以使用 datum->syntax 创建标识符:

#!r6rs
(import (rnrs)
(rnrs syntax-case))

(define-syntax make-predicate
(lambda (stx)
(define (s->p sym)
(string->symbol (string-append (symbol->string sym) "?")))

(syntax-case stx ()
[(_ name)
(with-syntax
([predicate (datum->syntax #'name (s->p (syntax->datum #'name)))])
#'(define (predicate v)
(and (pair? v)
(eq? (car v) 'name))))])))

(make-predicate circle)
predicate? ; ==> #<procedure-predicate?>
(predicate? '(predicate x)) ; ==> #t

如果您执行此操作后是#langracket而不是标准方案,我认为syntax-case存在并且与此兼容。另外我建议您阅读Greg Hendershott's fear of macros了解更多 Racket 特定功能。

你只是想知道它是如何完成的

嗯。如果你看SRFI-9 spec它提供了实现,甚至可以查看#langracket implementation of struct at github或者只需右键单击 DrRacket 中的符号并选择“打开定义文件”即可像打开任何其他文件一样打开源代码。这没有什么 secret ,但它可能比你想象的要稍微复杂一些。

注意:请注意,define-struct 不再是 #langracket 中的首选形式,而只是为了向后兼容而提供。 struct是首选。

关于struct - 如何在方案中实现Racket风格的结构?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47109163/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com