我想定义一个这样的函数:
(define (((lift fn) . gs) . args)
(apply fn (map (lambda (g) (apply g args)) gs)))
这基本上“提升”了一个函数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))
这适用于普通球拍。现在,我想将此功能移动到打字球拍中。这是我想出的类型声明:
(: lift (All (A ... ) (All (B ...) (All (C)
((B ... B -> C) ->
((A -> B) ... B ->
(A ... B -> C)))))))
这是我认为定义所说的:对于所有类型A0
, A1
, .. An
and B0
, B1
, ... Bn
, and C
:
lift
取 (B0
,B1
, ...Bn
的函数C
) 并产生:- 许多函数的函数(
Ai
toBi
,i
从 0 ton
)依次产生: - 的函数
Ai
,i
从 0 到n
,依次产生: - 一种
C
这不起作用:在最后一行(A ... B -> C)
我得到Type Checker: Type variable A must be used with ... in: A
.
这不是我在使用 Typed Racket 时遇到的第一个省略号问题,而且我认为这确实是对省略号的含义的根本误解。
作为旁注,如果我尝试将这些All
子句折叠成一个这样的子句:
(All (A ... B ... C) blah blah blah)
然后在第二行((B ... B - C) ->
我收到以下错误:(Type Checker: Used a type variable (B) not bound with ... as a bound on a ... in: B
指该行的第二个 B)。我也不是很明白。