如何在Racket中使用宏实现define-type和type-case?

问题描述 投票:0回答:1

plai方案中提供了define-type和type-case,但由于某种原因它们不存在于typed/racket中。我想使用宏在球拍中实现这些结构。

我想创建一个宏“def-user-type”,下面是我想使用的语法

    (def-user-type Shape
      [Rectangle ((l Number) (b Number))]
      [Circle    ((r radius))]
      [Blah      (())])

它的行为应该大致如下

    (define-type Shape (U Rectangle Circle Blah))
    (struct: Rectangle ([l : Number] [b Number]))
    (struct: Circle ([r : Number]))
    (struct: Blah ())

这就是我迄今为止所取得的成就。这是不正确的,并且球拍编译器给出的错误消息也没有帮助。

#lang typed/racket
(define-syntax define-user-type
  (syntax-rules()
    [(define-user-type type-name
       [sub-type ((field-name type) ...)]
       ...)
     ((define-type type-name (U sub-type ...))
     (struct: sub-type ([field-name : type] ...))
     ...)]))

请指导我。 谢谢!

macros racket plai
1个回答
4
投票

你似乎问了不止一个问题。

首先,Typed Racket 有一个

define-type
,但它可能与
#lang plai
中的版本有点不同。你可以在这里看到 plai 的
define-type
type-case
的实现

其次,您的宏存在一些问题。

  1. syntax-rules
    子句的右侧将
    define-type
    的结果应用为函数,这是行不通的。尝试使用
    begin
    组合表达式。

  2. 您对

    def-user-type
    宏的使用不遵循定义。该定义需要零个或多个
    (field-name type)
    对,但在
    Blah
    中,您给出
    ()
    ,这不是一对。

  3. radius
    是未定义类型

这是包含建议更改的宏版本:

#lang typed/racket

(define-syntax def-user-type
  (syntax-rules ()
    [(_ type-name [sub-type ((field-name type) ...)] ...)
     (begin
       (define-type type-name (U sub-type ...))
       (struct: sub-type ([field-name : type] ...)) ...)]))

(def-user-type Shape
  [Rectangle ((l Number) (b Number))]
  [Circle    ((r Number))]
  [Blah      ()])

这是一个使用

Rectangle
作为
Shape
的示例:

> ((λ: ([x : Shape]) x) (Rectangle 1 2))
- : Shape
#<Rectangle>
© www.soinside.com 2019 - 2024. All rights reserved.