Replicating the type of `apply`

Hello,

I am trying to replicate the type of apply:

tmp.rkt> apply
- : (All (a b) (-> (-> a * b) (Listof a) b))
#<procedure:apply>

So, I define my own function:

(: my-apply (All (a b) (-> (-> a * b) (Listof a) b)))
(define (my-apply f xs) (apply f xs))

I define a fixed-arity function f:

(: f (-> Number Number Number))
(define (f x y) (+ x y))

Testing time:

tmp.rkt> (apply f '(1 2))
- : Number
3
tmp.rkt> (my-apply f '(1 2))
; /home/scolobb/Candies/prj/racket/dds/tmp.rkt:30:0: Type Checker: Polymorphic function `my-apply' could not be applied to arguments:
; Argument 1:
;   Expected: (-> a * b)
;   Given:    (-> Number Number Number)
; Argument 2:
;   Expected: (Listof a)
;   Given:    (List One Positive-Byte)
; ...
;   /gnu/store/qck82j07zb03m4q66np999f8bcfyp6m6-racket-8.4/lib/racket/pkgs/typed-racket-lib/typed-racket/typecheck/tc-toplevel.rkt:665:0 tc-toplevel-form
tmp.rkt> ((inst my-apply Number Number) f '(1 2))
; /home/scolobb/Candies/prj/racket/dds/tmp.rkt:32:31: Type Checker: type mismatch
;   expected: (-> Number * Number)
;   given: (-> Number Number Number)
;   in: f
; ...

How do I replicate the type of apply? My actual use case to write the type for a function applying a list of functions.

Note that my-apply works OK with variable-arity functions, e.g.:

tmp.rkt> (my-apply + '(1 2))
- : Integer [more precisely: Nonnegative-Integer]
3

However, I would like to my-apply to handle both fixed- and variable-arity functions, like apply.

Just found a solution:

(: my-apply (All (b a ...) (-> (-> a ... b) (List a ...) b)))
(define (my-apply f xs) (apply f xs))
tmp.rkt> (my-apply f '(1 2))
- : Number
3
tmp.rkt> (my-apply + '(1 2 3))
- : Integer [more precisely: Positive-Index]
6

I am somewhat surprised that the type of apply literally copied and pasted does not work, but I've got myself a solution anyway, so no complaints :slight_smile:

1 Like

apply is handled specially by the type checker, so you can't replicate its behavior exactly for your own code.

2 Likes

Thanks @samth! I guessed as much, but it's helpful to have an official confirmation.