gpt4 book ai didi

macros - Racket :宏扩展内部匹配模式

转载 作者:行者123 更新时间:2023-12-04 22:29:34 26 4
gpt4 key购买 nike

有什么方法可以检测宏是否在模式匹配中扩展?

这是我想编写的示例宏,但它在 match-define 中失败:

#lang racket/base
(require racket/match (for-syntax racket/base syntax/parse))

(struct point (x y))

(define-syntax (friendly-point stx)
(syntax-parse stx
[(_ arg* ...)
#'(begin (printf "Now making a point\n") (point arg* ...))]
[_ #'(begin (printf "Hello point\n") point)]))

(define p (friendly-point 1 2))
;; Prints "Now making a point"

(match-define (friendly-point x y) p)
;; ERROR

最佳答案

是的。不要使用用 define-syntax 创建的普通语法转换器,而是使用 define-match-expander 创建一个可以 cooperate with match 的宏。

(require (for-syntax syntax/parse))

(define-match-expander positive
(syntax-parser
[(_ n)
#'(? positive? n)]))

(match 3
[(positive n) (~a n " is positive")])
; => "3 is positive"
define-match-expander 形式很灵活:它可用于创建只能在 match 内部使用的宏,但它也可用于创建根据使用方式扩展不同的宏,方法是提供两个转换器函数,一个用于每个上下文.这允许您拥有“上下文敏感”标识符,既可用作函数又可用作匹配扩展器。

(require (for-syntax syntax/parse)
(prefix-in base: racket/base))

(define-match-expander syntax
(syntax-parser
[(_ x)
#'(? syntax? (app syntax->datum x))])
(make-rename-transformer #'base:syntax))

(match (syntax (1 2 3))
[(syntax n) (~a n " is a syntax list")])

如果您需要更大的灵活性,您可以完全放弃 define-match-expander 并使用 prop:match-expander 结构类型属性定义自定义结构。这可以与 prop:procedure 结合以实现上述双参数功能,但它也可以保存状态,并且可以与其他结构类型属性(例如 prop:rename-transformer)配对,以允许相同的标识符在许多不同的上下文中起作用。

关于macros - Racket :宏扩展内部匹配模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35592869/

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