sub1的类型不匹配问题

Lyu*_*ing 5 racket typed-racket

我不知道为什么pick1中的sub1函数有类型不匹配的问题,但是pick0没有

(define-predicate one? One)
(: pick1 (-> Positive-Integer (Listof Any) Any))
(define pick1
  (?(n lat)
    (cond [(one? n) (car lat)]
          [else (pick1 (sub1 n)
                       (cdr lat))])))
Run Code Online (Sandbox Code Playgroud)

我已经尝试过这种解决方法,但是我认为这不是解决此问题的正确方法。

(: pick1-workaround (-> Positive-Integer (Listof Any) Any))
(define pick1-workaround 
  (?(n lat)
    (cond [(one? n) (car lat)]
          [else (pick1-workaround  (cast (sub1 n) Positive-Integer)
                                   (cdr lat))])))
Run Code Online (Sandbox Code Playgroud)

pick0没有这个问题。

;;(: pick0 (-> Natural (Listof Any) Any))
(define pick0
  (?(n lat)
    (cond [(zero? n) (car lat)]
          [else (pick0 (sub1 n)
                       (cdr lat))])))
Run Code Online (Sandbox Code Playgroud)

Sor*_*ase 5

您暗中想要Typed Racket推理的原因是,如果xin Positive-Integer - One,则(sub1 x)in Positive-Integer。尽管人们很容易看出这是真的,但我认为问题是Typed Racket不知道如何描述Positive-Integer - One= {2, 3, 4, ...}

另一方面,您的pick0作品。此版本pick1也适用:

(: pick1 (-> Positive-Integer (Listof Any) Any))
(define pick1
  (? (n lat)
    (define n* (sub1 n))
    (cond 
      [(zero? n*) (car lat)]
      [else (pick1 n* (cdr lat))])))
Run Code Online (Sandbox Code Playgroud)

我认为原因是Typed Racket知道if x是in Positive-Integer,然后(sub1 x)是in Natural,并且它认识到(sub1 x)else分支必须位于in Natural - {0} = Positive-Integer(通过出现键入),从而使其能够成功地对程序进行类型检查。