Racket 中的“哈希”之类的检查是否支持鸭子类型?

Do checks like `hash?` in Racket support duck-typing?

我是 Python 刚接触 Racket 的程序员...

我看过一些代码,例如:

(define table/c (and/c hash? (not/c immutable?)))

我理解这是对合同的使用,即 https://docs.racket-lang.org/reference/data-structure-contracts.html#%28def._%28%28lib._racket%2Fcontract%2Fbase..rkt%29._and%2Fc%29%29

所以这意味着这个库中任何接受 table/c arg 的地方,它应该是一个对象,它是一个 mutable hash-table.

我的问题是... Racket 是否支持此处的鸭子打字(特别是为了满足 hash? 的合同)?

说我想用 k/v 商店支持的东西替换基本哈希-table...是否有一个 'hash-table' 接口我可以实现,允许我的商店-支持自定义对象以通过 hash? 合同检查?

合同文档和 this for the hash? check 对我帮助不大。

我认为你真的想为此使用字典,但如果你受困于需要 hash? 进行合同检查的图书馆,那么你可以使用模仿者。

这是我写的一个函数,它尝试使用一个弱哈希,它有一个缓存,用于一些可能很昂贵的计算,由(错误命名的)filler 函数表示,该函数将在缺少键时被调用。

我不太确定这类事情的语义(而且我不是这方面的专家)但它在实践中有效。

(define (make-cache filler)
  (impersonate-hash
   (make-weak-hash '())
   (λ (ht key)
     ;; impersonate hash-ref by calling the filler
     (unless (hash-has-key? ht key)
       ;; I think this is safe as the key won't be dropped
       (hash-set! ht key (filler key)))
     (values key (λ (ht k v) v)))
   ;; Everything else is passed through
   (λ (ht k v)
     (values k v))
   (λ (ht k)
     k)
   (λ (ht k)
     k)))