首页 > 解决方案 > Racket 中的 `hash?` 之类的检查是否支持鸭子类型?

问题描述

我是 Racket 新手的 Python 程序员...

我看过一些代码,例如:

(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._和%2Fc%29%29

所以这意味着这个库中接受table/carg 的任何地方都应该是一个可变哈希表的对象。

我的问题是...... Racket 是否支持在这里进行鸭式打字(特别是为了满足合同hash?)?

假设我想用 ak/v 存储支持的东西替换基本哈希表...是否有我可以实现的“哈希表”接口允许我的存储支持的自定义对象通过hash?合同检查?

合同文档和支票文档hash?我没有多大帮助。

标签: racketcontractduck-typing

解决方案


我认为您真的想为此使用字典,但是如果您遇到需要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)))

推荐阅读