问题
I'm trying to add types to some numerical racket code in the hopes of making it faster, but I am stuck dealing with for/list macro expansion in the code below.
(: index-member ((Listof Any) (Listof Any) -> (Listof Index)))
(define (index-member xs ys)
(filter-not negative?
(for/list ([(ann i Index) (in-range (ann (length xs) Index))])
(if (member (list-ref xs i) ys) i -1))))
This function returns a list of indexes foreach x which is a member of y. It works in Racket, but I can't seem to get it past the type checker for Typed Racket. Specifically, the error is:
Type Checker: Error in macro expansion -- insufficient type information to typecheck. please add more type annotations in: (for/list (((ann i Index) (in-range (ann (length xs) Index)))) (if (member (list-ref xs i) ys) i -1))
Can you provide annotations that get this past the type checker and/or explain why these type annotations are insufficient?
回答1:
The key is to use the for/list:
form instead since it allows you to add type annotations over the basic for/list
form to give Typed Racket more guidance. I've made a few other adjustments to get the types to line up (e.g., using filter
over filter-not
, avoiding in-range
, etc.):
#lang typed/racket
(: index-member ((Listof Any) (Listof Any) -> (Listof Index)))
(define (index-member xs ys)
(filter index?
(for/list: : (Listof Integer) ([i : Index (length xs)])
(if (member (list-ref xs i) ys) i -1))))
This actually exposes a weakness in the type of filter-not
(filter
is smarter about the type of the list it returns), which I'll look into fixing.
来源:https://stackoverflow.com/questions/18513447/for-list-annotations-in-typed-racket