Open
Description
Thank you so much for typed racket.. I hope to be able to help improve it
What version of Racket are you using?
7.6
What program did you run?
#lang typed/racket
(provide Text Header Paragraph ToplevelElement Title PageAttribute Page
load-page)
(define-type Text String)
(define-type Header (List 'header Text))
(define-type Paragraph (List 'paragraph Text))
(define-type ToplevelElement (U Header Paragraph))
(define-type Title (List 'title String))
(define-type PageAttribute (U Title))
(define-type Page (List 'page (Listof PageAttribute) (Listof ToplevelElement)))
(: load-page (String . -> . Page))
(define (load-page id)
`(page
((title "Test page"))
((header "Test page") (paragraph "This is a test. How does it look?"))))
(: page-attr (Page (U 'title) . -> . (U #f PageAttribute)))
(define (page-attr p t)
(assoc t (second p)))
(: page-title (Page . -> . (U Title #f)))
(define (page-title p)
(let ([title (page-attr p 'title)])
(if title (second title) #f)))
What should have happened?
provide clear error message for fixing type error at (second title)
in last line
If you got an error message, please include it here.
Polymorphic function `second' could not be applied to arguments:
Types: (List* a r (Listof t)) -> (r : ((! (cadr (0 0)) False) | (: (cadr (0 0)) False)) : (cadr (0 0))
(Listof a) -> a
Arguments: Title
Expected result: (U False Title)
Discussion
In hindsight the problem was very simple, the (second title) returns a String but the function need a Title or #f. The bug was in the function as I meant it to return a String or #f.
I have a few highly naive ideas to improve the error message:
- Making the (cadr (0 0)) type easier to learn about. I searched the docs website, grepped this repo looking for type declarations of
second
or ofcadr
but couldn't find any. I still haven't found info about what the(cadr (0 0))
type means. I also tried copying it out to a define-type to track down the cadr type via xref, but it fails to parse at the|
(define-type second (List* a r (Listof t)) -> (r : ((! (cadr (0 0)) False) | (: (cadr (0 0)) False)) : (cadr (0 0))))
- You probably hear this too much, but if it displayed the type it was inferring for the expression (ex: Expected (U False Title) but got String) that would have made the issue very clear.