【发布时间】:2021-07-13 17:03:45
【问题描述】:
在我的answer 到this question 中,我发现您似乎经常需要为匿名函数的参数添加类型注释,这些匿名函数用作映射函数的参数:map、foldl 等等。
这里有两个简单的例子(所有这些都假设#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 中看到,它成功地从 x 和 y 的类型推断出 a 和 b 的类型。
我很可能只是对这里的某些事情感到困惑,但是因为我什至在 Typed Racket 方面都没有能力。
所以问题是:我是否感到困惑,这些匿名函数的参数类型真的不可知,或者只是类型检查器还不够聪明,无法推断出这种情况靠自己?
【问题讨论】:
标签: lisp racket typed-racket