簡體   English   中英

在類型化球拍中使用哈希聯合

[英]Using hash-union in typed racket

我正在使用 Typed Racket 中的 hash 表,並嘗試使用來自racket/hash的(無類型) hash-union function 。 使用require/typed將其導入我的模塊並調用它將通過類型檢查器並編譯。

#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)))

但是,實際運行它會導致合約失敗:

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解決此問題,這是我的計划)。

問題是 hash 表的鍵中的多態性不適用於從非類型化 Racket 導入 Typed Racket 時放置在其上的合約。 錯誤信息:

hash/c: contract violation
  expected: chaperone-contract?
  given: k33

(All (kv).... (Immutable-HashTable kv)....)中提到來自您的kk33

修復此錯誤的第一步是使用像Any這樣的具體類型而不是多態k ,如(All (v).... (Immutable-HashTable Any v)....)

之后的下一個錯誤可能類似於:

hash-union: contract violation
  expected: "hash-equal? (because the key contract is not a flat contract)"
  given: '#hasheqv()

這是因為hasheqhasheqv不能很好地與 Typed Racket 放在它上面的合約一起工作。 您可以通過使用hashhashalw來解決此問題,如(for/hash: (Immutable-HashTable Any Integer)....)

如果您遇到無法以類似方式解決的其他合同問題,也可以通過導入unsafely來繞過 Typed Racket 放置的合同,但這應該是最后的手段。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM