首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在类型化球拍中使用散列-并

在类型化球拍中使用散列-并
EN

Stack Overflow用户
提问于 2022-07-30 11:33:33
回答 1查看 42关注 0票数 1

我正在类型化Racket中使用哈希表,并尝试使用来自racket/hash的(非类型化)racket/hash函数。使用require/typed将其导入我的模块并调用它,它将传递类型检查器并进行编译。

代码语言:javascript
复制
#lang typed/racket/base

(require/typed racket/hash
  [hash-union (All (k v) (->* ((Immutable-HashTable k v))
                              (#:combine (-> v v v) #:combine/key (-> k v v v))
                              #:rest (HashTable k v)
                              (Immutable-HashTable k v)))])

(: pick-first (All (a) (-> a a a)))
(define (pick-first v1 v2) v1)

(: make-ci-table (-> String (Immutable-HashTable Char Integer)))
(define (make-ci-table pat)
  (let ([patlen (string-length pat)])
    ((inst hash-union Char Integer)
     (for/hasheqv : (Immutable-HashTable Char Integer) ([i (in-range patlen)])
       (values (char-upcase (string-ref pat i)) (- patlen 1 i)))
     (for/hasheqv  : (Immutable-HashTable Char Integer) ([i (in-range patlen)])
       (values (char-downcase (string-ref pat i)) (- patlen 1 i)))
     #:combine pick-first)))

但是,实际运行它将导致合同失败:

代码语言:javascript
复制
raco test: (submod "main.rkt" test)
hash/c: contract violation
  expected: chaperone-contract?
  given: k33
  context...:
   /usr/share/racket/collects/racket/contract/private/hash.rkt:61:0: hash/c
   /usr/share/racket/pkgs/typed-racket-lib/typed-racket/utils/hash-contract.rkt:28:0: hash/c/check-key
   /usr/share/racket/pkgs/typed-racket-lib/typed-racket/utils/hash-contract.rkt:22:0: immutable-hash/c
   /usr/share/racket/collects/racket/contract/private/parametric.rkt:26:36
   /usr/share/racket/collects/racket/contract/private/parametric.rkt:82:7: wrap
   /usr/share/racket/collects/racket/contract/private/parametric.rkt:100:10
   ...

普通球拍中的等价物运行良好。如果我正确地读取回溯跟踪,它似乎在测试表是否不可变(虽然我不知道为什么涉及伴侣契约,也不知道它为什么要获得其他值)。将rest类型更改为Immutable-HashTable不会改变任何事情,TR的for/hasheqv返回的表是不可变的。

对是什么原因以及如何解决它有什么想法吗?(除了使用for/fold或其他替代方法构建最终表之外,如果我不能用hash-union解决这个问题,这就是我的计划)。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-07-30 12:07:30

问题是,当您从非类型化的Racket中导入时,哈希表键中的多态不能很好地工作在输入Racket的契约中。错误信息:

代码语言:javascript
复制
hash/c: contract violation
  expected: chaperone-contract?
  given: k33

提到k33,它来自于(All (k v) .... (Immutable-HashTable k v) ....)中的k

修复此错误的第一步是使用像Any这样的具体类型,而不是多态k,就像在(All (v) .... (Immutable-HashTable Any v) ....)中那样。

之后的下一个错误可能如下所示:

代码语言:javascript
复制
hash-union: contract violation
  expected: "hash-equal? (because the key contract is not a flat contract)"
  given: '#hasheqv()

这是因为hasheqhasheqv不能很好地处理输入Racket的合同。您可以使用hashhashalw来修复这个问题,就像在(for/hash : (Immutable-HashTable Any Integer) ....)中一样。

如果您遇到了其他无法以类似方式解决的合同问题,也可以通过不安全地导入它,从而绕过提交给它的合同,但这应该是最后的解决办法。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73175239

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档