Hello,
If I define a function taking a heterogeneous list (List A ... A
) and try to coerce the argument to a pair with (assert lst pair?)
or an unless
guard, the program typechecks, but the assertion fails even when I pass a non-empty list. However, print debugging shows that both (pair? lst)
and (list? lst)
return #t
. Weirder still, if I define a different function that takes a homogeneous list (Listof A
) with a body identical to the first function, there is no discrepancy; this second function returns just fine.
Is this an issue of my understanding of List
in TR, or is this a TR bug (8.14 [cs])?
Example code:
#lang typed/racket/base
(: ttest-homo (All (A) (-> (Listof A) (Listof A))))
(define (ttest-homo lst)
(display (format "pair? ~a; list? ~a~%" (pair? lst) (list? lst)))
(unless (pair? lst) ; or (assert inp pair?)
(error 'wat))
lst)
(: ttest-hetero (All (A ...) (-> (List A ... A) (List A ... A))))
(define (ttest-hetero lst)
(display (format "pair? ~a; list? ~a~%" (pair? lst) (list? lst)))
(unless (pair? lst)
(error 'wat))
lst)
(define inp (ann '(1 2 3) (List Natural Natural Natural)))
(ttest-hetero inp)
;pair? #t; list? #t
;error: wat
(ttest-homo inp)
;pair? #t; list? #t
;'(1 2 3)
Background:
I am trying to grok polymorphic functions in TR and have been experimenting by trying to implement a simple function that copies a heterogeneous list. I ran into the above issue when trying to appease the TC. Incidentally, if anyone knows a way to implement the following function so that it typechecks with the given signature, please let me know.
(: list-copy (All (A ...) (-> (List A ... A) (List A ... A))))
(define (list-copy lst)
(if (null? lst)
lst
(cons (car lst) (list-copy (cdr lst)))))
Thank you
edited to correct output