简体   繁体   中英

Strange type mismatch error with Typed Racket propositions

I'm experimenting with propositions in Typed Racket and getting a type error I haven't seen before and can't make heads or tails of.

Example code:

#lang typed/racket/base
(require racket/fixnum)

; Version of fx= that takes two or more arguments (The TR version only takes 2)
(: fx=? (Fixnum Fixnum Fixnum * -> Boolean))
(define (fx=? a b . nums)
  (and (fx= a b)
       (andmap (lambda ([c : Fixnum]) (fx= a c)) nums)))

(: fxzero? (Fixnum -> Boolean : Zero))
(define (fxzero? i) (fx=? i 0))

Trying to compile this gives:

demo.rkt:12:20: Type Checker: type mismatch;
 mismatch in proposition
  expected: ((: i Zero) | (! i Zero))
  given: (Top | Top)
  in: (fx=? i 0)
  compilation context...:

Using = or fx= instead will compile and work as expected, and the fx=? function is usable elsewhere. Removing the : Zero proposition makes it compile and work too.

The expected and given types in that error message aren't in a notation I've seen before, and I can't find mention of it in the documentation. Anyone seen it before, or can explain what's different about my fx=? compared to other functions that's breaking my fxzero? ?

I think the first and largest issue here is that the type that you've applied to your fx=? function doesn't have any propositions attached to it, so functions using it aren't going to be able to infer anything about how it operates internally. With that said, I think you're going to have a heck of a time formulating a useful proposition that applies to your fx=? function. Specifically, you're asking TR to perform some extremely complex acrobatics through the type of andmap .

Put differently: When you formulate propositions like this, I claim TR doesn't go and explore and try to prove things about your code. Instead, occurrence typing means that it's possible to propagate information upward, if this information can be expressed using propositions and if these propositions can be glued together to get the result you want. It also appears that propositions are disallowed on types that include * in the argument list.

Just in case this isn't obvious; you know that this program type-checks fine, right?:

#lang typed/racket/base

(require racket/fixnum)

(: fxzero? (Fixnum -> Boolean : Zero))
(define (fxzero? i) (fx= i 0))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM