-
-
Notifications
You must be signed in to change notification settings - Fork 104
Description
Is your feature request related to a problem? Please describe.
I noticed that type constructors with zero parameters are sometimes treated inconsistently depending on context.
For example:
> (define-type (Nat) (Natural))
string:1:19: Type Checker: Error in macro expansion -- parse error in type;
bad syntax in type application: expected a type constructor
given a type: Nonnegative-Integer
in: (Natural)
[,bt for context]
> (define-type (Nat) Natural)
> (ann 123 (Nat))
string:1:9: Type Checker: Error in macro expansion -- parse error in type;
bad syntax in type application: expected a type constructor
given a type: Nonnegative-Integer
in: (Nat)
[,bt for context]
> (ann 123 Nat)
- : Integer [more precisely: Nonnegative-Integer]
123
> (: add (∀ () (→ Real Real Real)))
> (:print-type add)
(-> Real Real Real)
> (inst add)
string:1:6: Type Checker: Cannot instantiate non-polymorphic type (-> Real Real Real)
in: add
[,bt for context]Similarly, for structures:
> (struct () S ())
> (ann (S) (S))
string:1:9: Type Checker: type cannot be applied
type: S
in: (S)
[,bt for context]
> (ann (S) S)
- : S
#<S>Typed Racket seems to treat (T) as an invalid type expression when T is a nullary type constructor. This inconsistency causes problems when writing macros that automatically generate type applications.
For example, in a macro like:
(define-record-type (t ...) T
(make field-tag ...)
T?
field-spec ...)which expands to:
(struct (t ...) struct-spec ...)
(: make (∀ (t ...) (→ t ... (T t ...))))When (t ...) is (), the result type becomes (T), which triggers a type error — even though semantically it should just be T.
Describe the solution you'd like
I would like (T) to automatically expand to T when T is a nullary type constructor or just a type. This would make Typed Racket more consistent and make it easier to write macros that handle both parametric and non-parametric types uniformly.