正确理解和使用Typed Racket省略号

时间:2012-12-12 21:23:12

标签: types racket typed-racket

我想定义一个这样的函数:

(define (((lift fn) . gs) . args)
  (apply fn (map (lambda (g) (apply g args)) gs)))

这基本上是#34;升降机"函数fn使得它不接受正常参数,而是接受函数并生成一个新函数。所以,例如,

 (define add (lift +))
 (define sum-of-sin-and-cos (add sin cos))
 (sum-of-sin-and-cos 5) ; is equivalent to (+ (sin 5) (cos 5))

 (define sum-of-multiplication-and-division (add * /))
 (sum-of-multiplication-and-division 1 2 3 4 5) ; is equivalent to (+ (* 1 2 3 4 5) (/ 1 2 3 4 5))

这适用于普通的Racket。现在,我想将此功能移动到键入的球拍中。这是我提出的类型声明:

(: lift (All (A ... ) (All (B ...) (All (C)
             ((B ... B -> C) ->
                     ((A -> B) ... B ->
                               (A ... B -> C)))))))

以下是我认为定义所说的内容:适用于所有类型A0A1,... AnB0,{{ 1}},... B1Bn

  • C将(liftB0,... B1的函数转换为Bn并生成:
  • 许多函数的函数(CAiBi从0到i),它反过来产生:
  • nAi从0到i的函数,反过来生成:
  • a n

这不起作用:在最后一行C我得到(A ... B -> C)

这不是我使用Typed Racket时省略号的第一个问题,而且我认为这实际上是对省略号意图做什么的基本误解。

作为旁注,如果我尝试将Type Checker: Type variable A must be used with ... in: A条款折叠为这样的单个条款:

All

然后在第二行(All (A ... B ... C) blah blah blah)我收到以下错误:((B ... B - C) ->(指的是该行的第二行)。我也不太了解。

1 个答案:

答案 0 :(得分:5)

首先回答你的上一个问题,All的类型语法不允许同时绑定多个虚线变量,因为不清楚如何实例化它们。这与您在同一函数中不能有多个休息参数的原因相同。

关于lift,我认为你想要的类型是:

(: lift (All (C A ...)
             (All (B ...)
                  ((B ... B -> C)
                   ->
                   ((A ... A -> B) ... B 
                    ->
                    (A ... A -> C))))))

然后该函数通过一个注释:

(define (((lift fn) . gs) . args)
  (apply fn (map
             (λ: ([g : (A ... A -> B)])
               (apply g args))
             gs)))

由于嵌套的foralls,使用此函数需要一些显式注释;这是你的测试用例:

(define add ((inst (inst lift Number Number) Number Number) +))
(define add2 ((inst (inst lift Number Number Number Number Number Number)
                    Number Number)
              +))
(define sum-of-sin-and-cos (add sin cos))
(sum-of-sin-and-cos 5) ; is equivalent to (+ (sin 5) (cos 5))
(define sum-of-multiplication-and-division (add2 * /))    
(sum-of-multiplication-and-division 1 2 3 4 5)

请注意,我必须为add2创建单独的绑定,因为它们用于不同的类型。