2013-08-29 3 views
4

Я пытаюсь добавить типы к некоторому числовому ракетному коду в надежде сделать его быстрее, но я застрял в работе над расширением макроса/списка в коде ниже.для/список аннотаций в типизированном/racket

(: 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 x, который является членом y. Он работает в Racket, но, похоже, я не могу пройти мимо проверки типа Typed Racket. В частности, возникает ошибка:

Тип проверки: ошибка при расширении макроса - недостаточная информация о типе для typecheck. добавьте дополнительные аннотации типов в: (для/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

У меня есть связанный с этим вопрос. Как я могу обрабатывать предложение #: when в a для/first :? Я попробовал: '(for/first:: Index ((i: Index 5) #: when (> i 3)) i)', но все равно нужны дальнейшие аннотации. – wdkrnls

+0

К сожалению, циклы 'for' с предложениями' #: when' очень тонкие в Typed Racket. Один из способов записи: '(first (for/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

Смежные вопросы