[Buggy] Partially fixed match on type familes.
Fixed various application syntax bugs in match. Match still fails to infer the correct motive on type familes. This is due to indices being instantiated differently between motive and match clause.
This commit is contained in:
parent
09f47481ab
commit
b52dca0114
|
@ -14,8 +14,16 @@
|
||||||
(nil : (-> (A : Type) (List A)))
|
(nil : (-> (A : Type) (List A)))
|
||||||
(cons : (-> (A : Type) A (List A) (List A))))
|
(cons : (-> (A : Type) A (List A) (List A))))
|
||||||
|
|
||||||
(define list-ref
|
(define (list-ref (A : Type) (ls : (List A)))
|
||||||
(elim
|
(match ls
|
||||||
|
[nil (lambda (n : Nat) (none A))]
|
||||||
|
[(cons (A : Type) (a : A) (rest : (List A)))
|
||||||
|
(lambda (n : Nat)
|
||||||
|
(match n
|
||||||
|
[z (some A a)]
|
||||||
|
[(s (n-1 : Nat))
|
||||||
|
((recur rest) n-1)]))])
|
||||||
|
#;(elim
|
||||||
List
|
List
|
||||||
Type
|
Type
|
||||||
(lambda (A : Type) (ls : (List A))
|
(lambda (A : Type) (ls : (List A))
|
||||||
|
|
|
@ -44,7 +44,7 @@
|
||||||
|
|
||||||
(pattern
|
(pattern
|
||||||
type:expr
|
type:expr
|
||||||
#:attr name (format-id #'type "~a" (gensym)))))
|
#:attr name (format-id #'type "~a" (gensym 'anon-parameter)))))
|
||||||
|
|
||||||
;; A multi-arity function type; takes parameter declaration of either
|
;; A multi-arity function type; takes parameter declaration of either
|
||||||
;; a binding (name : type), or type whose name is generated.
|
;; a binding (name : type), or type whose name is generated.
|
||||||
|
@ -96,6 +96,10 @@
|
||||||
[(_ e1 e2 e3 ...)
|
[(_ e1 e2 e3 ...)
|
||||||
(quasisyntax/loc syn
|
(quasisyntax/loc syn
|
||||||
(#%app (#%app e1 e2) e3 ...))]))
|
(#%app (#%app e1 e2) e3 ...))]))
|
||||||
|
(module+ test
|
||||||
|
((lambda (A : (Type 1)) (B : (Type 1)) A)
|
||||||
|
Type
|
||||||
|
Type))
|
||||||
|
|
||||||
(define-syntax define-type
|
(define-syntax define-type
|
||||||
(syntax-rules ()
|
(syntax-rules ()
|
||||||
|
@ -157,28 +161,39 @@
|
||||||
#:attr indices
|
#:attr indices
|
||||||
'()
|
'()
|
||||||
#:attr decls
|
#:attr decls
|
||||||
(list #`(#,(gensym) : x)))
|
(list #`(#,(gensym 'anon-discriminant) : x)))
|
||||||
|
|
||||||
(pattern
|
(pattern
|
||||||
(x:id e:expr ...)
|
;; For some reason app is made explicit here
|
||||||
|
((~optional (~literal real-app)) x:id e:expr ...+)
|
||||||
#:attr inductive-name
|
#:attr inductive-name
|
||||||
#'x
|
#'x
|
||||||
#:attr indices
|
#:attr indices
|
||||||
(attribute e)
|
(attribute e)
|
||||||
#:attr names
|
#:attr names
|
||||||
(for/list ([e (attribute e)])
|
(for/list ([e (attribute e)])
|
||||||
(format-id e "~a" (gensym)))
|
(format-id e "~a" (gensym 'anon-index)))
|
||||||
#:attr types
|
#:attr types
|
||||||
;; TODO: Detect failure, report error/suggestions
|
;; TODO: Detect failure, report error/suggestions
|
||||||
(for/list ([e (attribute e)])
|
(for/list ([e (attribute e)])
|
||||||
(type-infer/syn e))
|
(or (type-infer/syn e)
|
||||||
|
(raise-syntax-error
|
||||||
|
'match
|
||||||
|
(format
|
||||||
|
"Could not infer type of index ~a"
|
||||||
|
e)
|
||||||
|
e)))
|
||||||
#:attr decls
|
#:attr decls
|
||||||
(append
|
(append
|
||||||
(for/list ([name (attribute names)]
|
(for/list ([name (attribute names)]
|
||||||
[type (attribute types)])
|
[type (attribute types)]
|
||||||
#`(name : type))
|
[src (attribute e)])
|
||||||
|
(quasisyntax/loc src
|
||||||
|
(#,name : #,type)))
|
||||||
;; TODO: quasisyntax/loc
|
;; TODO: quasisyntax/loc
|
||||||
(list #`(#,(gensym) : ((x e ...) #,@(attribute names)))))))
|
(list
|
||||||
|
(quasisyntax/loc #'x
|
||||||
|
(#,(gensym 'anon-discriminant) : (x #,@(attribute names))))))))
|
||||||
|
|
||||||
;; todo: Support just names, inferring types
|
;; todo: Support just names, inferring types
|
||||||
(define-syntax-class match-declaration
|
(define-syntax-class match-declaration
|
||||||
|
@ -202,7 +217,7 @@
|
||||||
'())
|
'())
|
||||||
|
|
||||||
(pattern
|
(pattern
|
||||||
(x:id d:match-declaration ...)
|
(x:id d:match-declaration ...+)
|
||||||
#:attr local-env
|
#:attr local-env
|
||||||
(for/fold ([d (make-immutable-hash)])
|
(for/fold ([d (make-immutable-hash)])
|
||||||
([name (attribute d.name)]
|
([name (attribute d.name)]
|
||||||
|
@ -224,11 +239,13 @@
|
||||||
(for/fold ([decls (attribute d.decls)])
|
(for/fold ([decls (attribute d.decls)])
|
||||||
([type-syn (attribute d.types)]
|
([type-syn (attribute d.types)]
|
||||||
[name-syn (attribute d.names)]
|
[name-syn (attribute d.names)]
|
||||||
|
[src (attribute d.decls)]
|
||||||
;; NB: Non-hygenic
|
;; NB: Non-hygenic
|
||||||
|
;; BUG TODO: This fails when D is an inductive applied to arguments...
|
||||||
#:when (cur-equal? type-syn D))
|
#:when (cur-equal? type-syn D))
|
||||||
(let ([ih-name (quasisyntax/loc d #,(format-id name-syn "ih-~a" name-syn))]
|
(define/syntax-parse type:inductive-type-declaration type-syn)
|
||||||
;; BUG TODO: This is broken; motive must be applied to indices and such, too
|
(let ([ih-name (quasisyntax/loc src #,(format-id name-syn "ih-~a" name-syn))]
|
||||||
[ih-type #`(#,motive #,name-syn)])
|
[ih-type #`(#,motive #,@(attribute type.indices) #,name-syn)])
|
||||||
(dict-set! ih-dict (syntax->datum name-syn) ih-name)
|
(dict-set! ih-dict (syntax->datum name-syn) ih-name)
|
||||||
(append decls (list #`(#,ih-name : #,ih-type)))))))
|
(append decls (list #`(#,ih-name : #,ih-type)))))))
|
||||||
|
|
||||||
|
@ -289,11 +306,19 @@
|
||||||
'match
|
'match
|
||||||
"Could not infer return type. Try using #:return to declare it."
|
"Could not infer return type. Try using #:return to declare it."
|
||||||
syn)))
|
syn)))
|
||||||
|
;; BUG TODO: return-type is inferred with the indexes of the branches, but those must be abstracted in the motive...
|
||||||
(~bind (motive (quasisyntax/loc syn
|
(~bind (motive (quasisyntax/loc syn
|
||||||
(lambda #,@(attribute D.decls) return-type))))
|
(lambda #,@(attribute D.decls) return-type))))
|
||||||
(~var c (match-clause (attribute D) (attribute motive))) ...)
|
(~var c (match-clause (attribute D) (attribute motive))) ...)
|
||||||
(quasisyntax/loc syn
|
(quasisyntax/loc syn
|
||||||
(elim D.inductive-name #,(type-infer/syn (attribute return-type))
|
(elim
|
||||||
|
D.inductive-name
|
||||||
|
#,(or
|
||||||
|
(type-infer/syn (attribute return-type))
|
||||||
|
(raise-syntax-error
|
||||||
|
'match
|
||||||
|
"Could not infer type of motive. Sorry, you'll have to use elim."
|
||||||
|
syn))
|
||||||
motive
|
motive
|
||||||
c.method ...
|
c.method ...
|
||||||
#,@(attribute D.indices)
|
#,@(attribute D.indices)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user