次のような関数を定義したいと思います。
(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
およびB0
、、B1
... Bn
、およびC
:
lift
B0
( 、、、B1
...Bn
toの関数)を取り、以下C
を生成します。- 多くの関数(
Ai
からBi
、i
0からn
)の関数。これにより、次の関数が生成されます。 - 0から
Ai
、までのの関数。これにより、次のようになります。i
n
- a
C
これは機能しません。最後の行(A ... B -> C)
でType Checker: Type variable A must be used with ... in: A
。
これは、Typed Racketを使用しているときに発生した省略記号の最初の問題ではありません。これは、省略記号の意味についての根本的な誤解の事例だと思います。
All
ちなみに、句を次のように1つにまとめようとすると、次のようになります。
(All (A ... B ... C) blah blah blah)
次に、2行目((B ... B - C) ->
に次のエラーが表示されますType Checker: Used a type variable (B) not bound with ... as a bound on a ... in: B
(その行の2番目のBを参照)。私もそれをよく理解していません。