[英]How to implement Racket-style struct in scheme?
在球拍中,您有机会创建和使用这样的结构类型
(define-struct example (a b))
(define var (make-example 1 2))
(example? var)
(example-a var)
我正在尝试在使用宏的方案中实现类似这样的内容,但是我在创建带有组合名称的过程(make-example 1 2)
遇到了问题,其中绝对不是示例 。 是否可以使用此类名称定义过程或其他方法来解决此问题?
无需查看其他语言来查找已经存在的功能。 它只有一个不同的名称: records !
它是在SRFI-9定义记录类型中定义的 ,并且最新的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
如果执行此操作后是#lang racket
而不是标准Scheme,那么我认为存在syntax-case
并与此兼容。 另外,我建议您阅读Greg Hendershott对于更多球拍特定功能的恐惧,关注宏 。
好。 如果您查看SRFI-9规范,它会提供实现,甚至在github上查看struct的 #lang racket
实现,或者只需右键单击DrRacket中的符号,然后选择“打开定义文件”即可像其他任何文件一样打开源。 这没有什么秘密,但是它可能比您讲的要复杂一些。
注意:请注意,在#lang racket
, define-struct
不再是首选形式,而只是为了向后兼容而提供。 struct
是首选。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.