Types 这两种类型注释之间的区别是什么?为什么它们不同?

Types 这两种类型注释之间的区别是什么?为什么它们不同?,types,racket,typed-racket,Types,Racket,Typed Racket,我试图从《小阴谋家》一书中为这个函数添加类型 (define rember-fc (λ(test?) (λ (a l) (cond [(null? l) '()] [(test? a (car l)) (cdr l)] [else (cons (car l) ((rember-fc test?) a (cdr l)))])))) 此类型会导致错误。 (: re

我试图从《小阴谋家》一书中为这个函数添加类型

(define rember-fc
  (λ(test?)
    (λ (a l)
      (cond [(null? l) '()]
            [(test? a (car l)) (cdr l)]
            [else
             (cons (car l)
                   ((rember-fc test?) a (cdr l)))]))))
此类型会导致错误。

(: rember-fc  (∀ (a) (-> (-> Any Any Boolean)  (-> a (Listof a) (Listof a)))))
(: rember-fc  (-> (-> Any Any Boolean)  (∀ (a) (-> a (Listof a) (Listof a)))))
这种类型有效。

(: rember-fc  (∀ (a) (-> (-> Any Any Boolean)  (-> a (Listof a) (Listof a)))))
(: rember-fc  (-> (-> Any Any Boolean)  (∀ (a) (-> a (Listof a) (Listof a)))))

我想知道为什么这两种类型会导致不同的结果,区别是什么?

该函数可以在类型签名的第一个版本下工作

(: rember-fc  (∀ (a) (-> (-> Any Any Boolean)  (-> a (Listof a) (Listof a)))))
如果在递归调用中使用函数的位置添加注释,则替换

((rember-fc test?) a (cdr l))

其中,
inst
类型注释允许它进行类型检查

此函数的使用有两个应用程序,一个内部应用程序和一个外部应用程序。首先对内部应用程序进行类型检查,只有当外部应用程序具有内部应用程序的具体类型时,才会对其进行类型检查

(rember fc test?)
具有forall类型且
a
(cdr l)
提供信息时,Typed Racket的类型推断算法足够智能,可以计算出
((rember fc test?)a(cdr l))中的forall变量是什么。如果FALALL处于中间,内部应用程序不需要类型推断,外部应用程序类型推断成功,因为外部应用程序参数提供信息。
但是,类型推断不够智能,无法判断
rember fc
何时具有forall类型,并且
test?
没有在内部应用程序中提供信息。
a
(cdr l)
仅在以后的外部应用程序中应用。当类型推断无法理解它时,它会在内部应用程序中猜测
Any
,并且只会在以后的外部应用程序中发现猜测是错误的

因此,这两个工作版本是:

(: rember-fc  (∀ (a) (-> (-> Any Any Boolean)  (-> a (Listof a) (Listof a)))))
(define rember-fc
  (λ (test?)
    (λ (a l)
      (cond [(null? l) '()]
            [(test? a (car l)) (cdr l)]
            [else
             (cons (car l)
                   (((inst rember-fc a) test?) a (cdr l)))]))))
以及: