【问题标题】:How to implement define-type and type-case in Racket using macros?如何使用宏在 Racket 中实现定义类型和类型案例?
【发布时间】:2013-08-08 16:23:39
【问题描述】:

在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


    【解决方案1】:

    您似乎在问不止一个问题。

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

    其次,你的宏有几个问题。

    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>
    

    【讨论】:

      猜你喜欢
      • 2020-03-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-11
      • 2017-04-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多