2013-08-29 145 views
4

我想添加类型的一些数字球拍代码,希望使其更快,但我坚持处理/下面的代码宏扩展。for/list注释类型/球拍

(: 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)))) 

这个函数返回一个索引列表foreach,它是y的一个成员。它适用于Racket,但似乎无法通过Typed Racket的类型检查程序。具体而言,错误是:

类型检查器:宏扩展中的错误 - 类型信息不足以进行类型检查。请添加更多的类型注释:(for/list(((ann i Index)(in-range(ann(length xs)Index)))(if(member(list-ref xs i)ys)i -1) )

你能否提供注解,让它通过类型检查器和/或解释为什么这些类型注释不够?

回答

4

关键是要使用for/list:表单,因为它允许您在基本for/list表单上添加类型注释,以便为Typed Racket提供更多指导。我做了一些其他调整以获得各类排队(例如,使用filter超过filter-not,避免in-range等):

#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)))) 

这实际上暴露在filter-not类型的弱点(filter是更清楚它返回的列表的类型),我会研究修复。

+0

我有一个相关的问题。如何处理for/first:中的#:when子句?我试过:'(for/first::Index((i:Index 5)#:when(> i 3))i)'但仍需要进一步的注释。 – wdkrnls

+0

不幸的是,'':''''循环与'#:when'子句在Typed Racket中非常成功。一种写法是(首先(对/ list::(Listof Index)((i:Byte 5)#:when(> i 3))i))',但这可能效率较低。您也可以手动编写循环。我们对如何使它在未来更加精确有一些想法。 –

+0

'for/list:'实际上是不推荐的形式 - 标准的'for/list'可以用类型信息注释。请参阅http://docs.racket-lang.org/ts-reference/special-forms.html#%28form._%28%28lib._typed-racket%2Fbase-env%2Fprims..rkt%29._for%29 %29 – jtmoulia