微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

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

在我的 answerthis question 中,我发现您似乎经常需要为匿名函数的参数添加类型注释,用作映射函数的参数:map、{{1 }} 等等。

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

我希望这样做:

#lang typed/racket

但事实并非如此:您需要告诉它 (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))

在最后一个函数中,您可以从 GUI 中看到它已成功地从 (define (gg (x : Number) (y : Number)) ((λ (a b) (+ a b)) x y)) a 的类型推断出 bx 的类型。

很可能我只是对这里的某些事情感到困惑,但是因为我什至几乎无法胜任 Typed Racket。

所以问题是:我是否感到困惑,这些匿名函数的参数类型真的是不可知的,还是只是类型检查器(还)不够聪明而无法推断出这种情况靠自己?

解决方法

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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。