add stlc tests for recursive define-types (ie intlist)
This commit is contained in:
parent
e490825797
commit
dff0f2b79f
|
@ -100,4 +100,29 @@
|
|||
(check-type-error (define (maybeint->wrong [maybint : MaybeInt])
|
||||
(cases maybint
|
||||
[None () #f]
|
||||
[Just (x) x])))
|
||||
[Just (x) x])))
|
||||
|
||||
(define-type IntList (variant (Null) (Cons Int IntList)))
|
||||
(check-type-and-result (Null) : IntList => (Null))
|
||||
(check-type-and-result (Cons 1 (Null)) : IntList => (Cons 1 (Null)))
|
||||
(check-type-error (Cons "one" (Null)))
|
||||
(check-type-error (Cons 1 2))
|
||||
(define (map/IntList [f : (→ Int Int)] [lst : IntList])
|
||||
(cases lst
|
||||
[Null () (Null)]
|
||||
[Cons (x xs) (Cons (f x) (map/IntList f xs))]))
|
||||
(check-type-and-result (map/IntList add1 (Null)) : IntList => (Null))
|
||||
(check-type-and-result (map/IntList add1 (Cons 1 (Null))) : IntList => (Cons 2 (Null)))
|
||||
(check-type-and-result (map/IntList add1 (Cons 2 (Cons 1 (Null))))
|
||||
: IntList => (Cons 3 (Cons 2 (Null))))
|
||||
(check-type-error (map/IntList (λ ([n : Int]) #f) (Null)))
|
||||
(define-type BoolList (variant (BoolNull) (BoolCons Bool BoolList)))
|
||||
(define (map/BoolList [f : (→ Bool Int)] [lst : BoolList])
|
||||
(cases lst
|
||||
[BoolNull () (Null)]
|
||||
[BoolCons (x xs) (Cons (f x) (map/BoolList f xs))]))
|
||||
(check-type (map/BoolList (λ ([b : Bool]) (if b 0 1)) (BoolNull)) : IntList)
|
||||
(check-type-and-result
|
||||
(map/BoolList (λ ([b : Bool]) (if b 0 1)) (BoolCons #f (BoolNull)))
|
||||
: IntList => (Cons 1 (Null)))
|
||||
(check-not-type (map/BoolList (λ ([b : Bool]) (if b 0 1)) (BoolNull)) : BoolList)
|
16
stlc.rkt
16
stlc.rkt
|
@ -21,8 +21,12 @@
|
|||
[datum/tc #%datum] [module-begin/tc #%module-begin]
|
||||
[cons/tc cons] [null/tc null] [null?/tc null?] [first/tc first] [rest/tc rest]))
|
||||
|
||||
;; TODO:
|
||||
;; - type of top level (or module level) vars not checked
|
||||
;; Simply-Typed Lambda Calculus+
|
||||
;; Features:
|
||||
;; - letrec
|
||||
;; - lists
|
||||
;; - user (recursive) function definitions
|
||||
;; - user (recursive) (variant) type-definitions
|
||||
|
||||
;; for types, just need the identifier bound
|
||||
(define-syntax-rule (define-builtin-type τ) (begin (define τ #f) (provide τ)))
|
||||
|
@ -176,7 +180,7 @@
|
|||
#:with ((x ...) ...) (stx-map generate-temporaries #'((τ_fld ...) ...))
|
||||
#:when (Γ (type-env-extend #'([Cons (→ τ_fld ... τ)] ...)))
|
||||
#'(begin
|
||||
(struct Cons (x ...)) ...)]))
|
||||
(struct Cons (x ...) #:transparent) ...)]))
|
||||
(define-syntax (cases stx)
|
||||
(syntax-parse stx
|
||||
[(_ e [Cons (x ...) body ... body_result] ...)
|
||||
|
@ -184,7 +188,7 @@
|
|||
#:with (Cons+ ...) (stx-map expand/df #'(Cons ...))
|
||||
#:with ((→ τ ... τ_Cons) ...) (stx-map typeof #'(Cons+ ...))
|
||||
#:when (stx-andmap (λ (τ) (assert-type #'e+ τ)) #'(τ_Cons ...))
|
||||
#:with ((lam xs+ body+ ... body_result+) ...)
|
||||
#:with ((lam (x+ ...) body+ ... body_result+) ...)
|
||||
(stx-map (λ (bods xs τs)
|
||||
(with-extended-type-env
|
||||
(stx-map list xs τs)
|
||||
|
@ -197,7 +201,7 @@
|
|||
#:when (or (null? (syntax->list #'(τ_result ...)))
|
||||
(andmap (λ (τ) (type=? τ (car (syntax->list #'(τ_result ...)))))
|
||||
(cdr (syntax->list #'(τ_result ...)))))
|
||||
#'(match e+ [(Cons+ x ...) body+ ... body_result+] ...)]))
|
||||
#`(match e+ [(Cons+ x+ ...) body+ ... body_result+] ...)]))
|
||||
|
||||
;; typed forms ----------------------------------------------------------------
|
||||
(define-syntax (datum/tc stx)
|
||||
|
@ -379,7 +383,7 @@
|
|||
#:with (τ ...) (template ((?@ . mb-form.τ) ...))
|
||||
#:with (e ...) (template ((?@ . mb-form.e) ...))
|
||||
#:when (Γ (type-env-extend #'([f τ] ...)))
|
||||
#:when (printf "fvs :~a\n" (fvs))
|
||||
; #:when (printf "fvs :~a\n" (fvs))
|
||||
;; error: "Just10: unbound identifier; also, no #%top syntax transformer is bound"
|
||||
;; cause: for struct def, define-values must come before define-syntaxes
|
||||
(quasisyntax/loc stx
|
||||
|
|
Loading…
Reference in New Issue
Block a user