是否可以通过映射函数和 lambda 使 Typed Racket 推断类型?

Is it possible to make Typed Racket infer types through mapping functions and lambdas?

在我的 answer to this question 中,我发现您似乎经常需要为用作映射函数参数的匿名函数的参数添加类型注释:mapfoldl 等等上。

这里有两个简单的例子(所有这些都假设 #lang typed/racket,我使用的是 Racket 8.0)。

我想要这个工作:

(define (f (l : (Listof Number)))
  : (Listof Number)
  (map (λ (x)
         (+ x 1))
       l))

但它不是:你需要告诉它 x 的参数是 Number:

(define (f (l : (Listof Number)))
  : (Listof Number)
  (map (λ ((x : Number))
         (+ x 1))
       l))

或者您可以使用 for/list,现在您不需要注释:

(define (f (l : (Listof Number)))
  : (Listof Number)
  (for/list ([x (in-list l)])
    (+ x 1)))

另一方面,这将起作用:

(define (g (l : (Listof Number)))
  : Number
  (foldl + 0 l))

但是如果我将其替换为(有点傻,但我想要一个小例子)

(define (g (l : (Listof Number)))
  : Number
  (foldl (λ (x y) (+ x y))  0 l))

失败,需要转成

(define (g (l : (Listof Number)))
  : Number
  (foldl (λ ((x : Number) (y : Number)) (+ x y))  0 l))

只有当匿名函数作为参数传递时才会发生这种情况,正如我所看到的,因为这个(又是愚蠢的)函数是可以的:

(define (gg (x : Number) (y : Number))
  ((λ (a b) (+ a b))
   x y))

在最后一个函数中,您可以从 GUI 中看到它已成功从 xy 的类型推断出 ab 的类型。

我很可能只是对这里的某些东西感到困惑,但是因为我什至连 Typed Racket 的能力都没有。

所以问题是:我是不是很困惑,这些匿名函数的参数类型真的是不可知的,或者只是类型检查器(还)不够聪明自己推论?

我不确定您所说的“不可知”是什么意思,但这确实是 Typed Racket 的工作原理。如果您应用多态函数,它不会使用参数的类型来推断其他参数的类型。但是它确实使用参数的类型来推断最后一个例子中的参数类型。