Typed Racket 是否提供类型安全的 list-ref 函数?

Is there a type-safe list-ref function provided by Typed Racket?

Typed Racket 是否提供类型安全的 list-ref 函数?

如果您尝试访问越界的索引,list-ref 函数似乎会引发错误:

> (require typed/racket)
> (list-ref '(1 2 3) 100)
; list-ref: index too large for list
;   index: 100
;   in: '(1 2 3)

list-ref returns 错误类型是有道理的:

> list-ref
- : (All (a) (-> (Listof a) Integer a))

我认为类型安全的版本会有如下类型:

(: list-ref (All (a) (-> (Listof a) Integer (Option a)))

如果类型安全的 list-ref 函数是从 Typed Racket 的某处提供的,我将如何找到它?

如果这个类型安全的 list-ref 函数不存在,那为什么不呢?看来这个功能一般都会有用。

据我所知不存在。

您提议的 (All (a) (-> (Listof a) Integer (Option a))) 的一个问题是 (Option a) 只是 (U #f a)。也就是说,您必须用 #f 表示“none”。但是如果你有一个 (Listof Boolean)list-ref*(你的 list-ref 的变体)returns #f,你怎么知道是不是因为索引已经出来了边界,或者因为元素确实是 #f?

解决这个问题的一种可能方法是用盒子之类的东西包裹“一些”变体,并相应地调整类型。例如,

(: list-ref* (All (a) (-> (Listof a) Integer (Option (Boxof a)))))
(define (list-ref* xs i)
  (with-handlers ([exn:fail? (λ (_) #f)])
    (box (list-ref xs i))))

请注意,换行会影响性能,这也许可以解释为什么它不包含在库中。