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

时间:2013-08-08 16:23:39

标签: macros racket

define-type和type-case在plai方案中提供,但由于某种原因它们不存在于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 ())

这是我迄今取得的成就。它是不正确的,并且由racket编译器给出的错误消息也没有帮助。

#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] ...))
     ...)]))

请指导我。 谢谢!

1 个答案:

答案 0 :(得分:4)

你好像问了不止一个问题。

首先,Typed Racket有一个define-type,但它可能与#lang plai中的版本略有不同。你可以看到plai的define-typetype-case here的实现。

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

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>