2013-08-29 66 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