5
votes

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

1 Answers

5
votes

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.