简体   繁体   中英

for/list annotations in typed/racket

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?

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 (eg, 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM