for/list annotations in typed/racket

racket, typed-racket

Solution

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.

Problem

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?

Original source