9.0.0.2
| (data type-signature | | maybe-prefix-form | | clause ...) |
|
| |
| type-signature | | = | | type-name | | | | | | | (type-name type-variable ...) | | | | | | | | maybe-prefix-form | | = | | #:prefix | | | | | | | #:prefix prefix-id | | | | | | | | clause | | = | | [name param ...] | | | | | | | | param | | = | | type | | | | | | | [param-name type] |
|
Just like the data type you would see in Haskell and ML, which supports parametric polymorphism. The prefix form is for namespacing the constructor of data type. The following is a normal usage, the constructors are all without namespacing.
| (data expr |
| [Var (name : Symbol)] |
| [abs (name : Symbol) (body : expr)] |
| [app (fn : expr) (arg : expr)] |
| [pi (name : Symbol) (e : expr) (body : expr)] |
| [type (level : Integer)] |
| [nat] |
| [zero] |
| [succ (n : expr)] |
| [rec expr expr expr expr] |
| [id expr expr expr] |
| [refl expr] |
| [J expr expr expr expr expr expr]) |
To have namespacing prefix, use the following code. The data type still Expr here, but the constructors will get E: prefix automatically.
| (data Expr #:prefix E |
| [Int Integer] |
| [Add Expr Expr]) |
| |
| (: Eval : Expr -> Integer) |
| (define (Eval e) |
| (match e |
| [(E:Int v) v] |
| [(E:Add l r) (+ (Eval l) (Eval r))])) |
| |
| (Eval (E:Add (E:Int 1) (E:Int 2))) |
And if you require #:prefix but didn’t provide an identifier, it will use data type LIST as prefix.
| (data (LIST T) #:prefix |
| [Nil] |
| [Cons T (LIST T)]) |
| |
| (: Len : (∀ (T) (LIST T) -> Natural)) |
| (define (Len L) |
| (match L |
| [(LIST:Nil) 0] |
| [(LIST:Cons t Tail) (add1 (Len Tail))])) |
| |
| (Len (LIST:Cons #t (LIST:Nil))) |