[英]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)....)
中提到來自您的k
的k33
。
修復此錯誤的第一步是使用像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()
這是因為hasheq
和hasheqv
不能很好地與 Typed Racket 放在它上面的合約一起工作。 您可以通過使用hash
或hashalw
來解決此問題,如(for/hash: (Immutable-HashTable Any Integer)....)
。
如果您遇到無法以類似方式解決的其他合同問題,也可以通過導入unsafely來繞過 Typed Racket 放置的合同,但這應該是最后的手段。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.