【问题标题】:Is it possible to make Typed Racket infer types through mapping functions and lambdas?是否可以通过映射函数和 lambdas 使 Typed Racket 推断类型?
【发布时间】:2021-07-13 17:03:45
【问题描述】:

在我的answerthis 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 方面都没有能力。

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

【问题讨论】:

    标签: lisp racket typed-racket


    【解决方案1】:

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

    【讨论】:

    • 好的,谢谢。我想类型系统距离能够推断出对人类来说是显而易见的事情还有很长的路要走(尽管 CMUCL/SBCL 在这种情况下可以做有用的事情,尽管它可能通过 hack 来做)。
    • 我认为这更多的是关于类型系统的工作原理,而不是它是否使用 hack——Haskell 会推断出这一点,因为它使用了非常不同的算法和方法。
    猜你喜欢
    • 2012-10-14
    • 2017-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-13
    • 2011-06-30
    • 2018-03-02
    相关资源
    最近更新 更多