2017-05-10 4 views
0

Ich habe die folgenden Arten in Racket definiert:Anlage auf definierte Typen in Racket

(define-type vname (Pairof String Integer)) 

(define-type term (U vname (Listof (Pairof String term)))) 

(define-type subst (Listof (Pairof vname term))) 

Wie würde ich eine Prozedur (lift s t) mit Signatur definieren (-> subst term term), die auf konditioniert ist, ob t vom Typ vname oder (Listof (Pairof String term))? Gibt es eine einfache Möglichkeit, den tatsächlichen Typ eines Union-Typs zu testen? Wenn ich stattdessen (define-type term (U String Integer)) hätte, könnte ich string? verwenden, um zu testen, ob t eine Zeichenfolge ist; Wie würde ich das auf meine Situation ausdehnen?

Antwort

0

Eine Union ist keine diskriminierte Einheit, daher gibt es nicht automatisch eine Möglichkeit, dies zu tun. In diesem speziellen Fall können Sie jedoch zwischen den beiden unterscheiden, da vname immer ein Paar mit Integer in der Position cdr ist, während ein Wert vom Typ (Listof (Pairof String term)) entweder '() ist oder ein Paar mit einem (möglicherweise leeren) ist. Liste in der cdr Position. So das Prädikat vname? könnte definiert werden als:

(define (vname? x) 
    (and (pair? x) (exact-integer? (cdr x)))) 
1

ich in ähnliche Probleme in typisierten Racket laufen habe und ich fand es einfacher structs für alle meine nicht-triviale Typen zu definieren. Dann können Sie zwischen Typen unterscheiden, die die Strukturprädikate verwenden, z.

(struct vname (name val)) 
(vname? (struct "foo" 5)) 
+0

Aber wie würde ich definieren "Term" mit einer Struktur? – Simeon

+0

Ich kenne Ihr Problem nicht. Aber es sieht so aus, als könnten Sie ein '(struct foo (str term)' und dann 'definieren (type-type (U vname (Listof foo))'. Sie könnten sogar eine Struktur definieren, um die Liste selbst zu umbrechen). – Gibstick