I'm trying to type annotate the following function in typed/racket.
(define (add . vals)
(apply map (lambda (x y) (+ x y)) vals))
Since add is a variable arity function, I've given the input type as Any *. As the map function returns a list of results, it could have type (Listof Any). So I tried annotating it with (: add (-> Any * (Listof Any))
.
However, the typechecker fails on the function body with error:
stacker.rkt:26:2: Type Checker: Bad arguments to function in `apply':
Domains: (-> a b ... b c) (Listof a) (Listof b) ... b
(-> a c) (Pairof a (Listof a))
Arguments: (case-> (-> Nonnegative-Fixnum Nonpositive-Fixnum Fixnum) (-> Nonpositive-Fixnum Nonnegative-Fixnum Fixnum) (-> Index Index Nonnegative-Fixnum) (-> Zero Number Number) (-> Number Zero Number)) (Listof Any)
in: (apply map (lambda (x y) (+ x y)) vals)
It's a rather confusing error message to decode and any help with reasoning about this would be much appreciated. I tried running the same code in
Like Sorawee mentioned in a comment, this signature doesn't make any sense for your code. The use of the lambda constrains it to exactly two arguments, both of which should be lists of Number
, Real
, Integer
, Float
, etc. to satisfy +
's type. And since there's only two arguments, why use apply
? Here's a fixed version, and one that takes one or more lists to compare that does use apply
:
(: add : (Listof Number) (Listof Number) -> (Listof Number))
(define (add l1 l2)
(map + l1 l2))
(: add-many : (Listof Number) (Listof Number) * -> (Listof Number))
(define (add-many l1 . lists)
(apply map + l1 lists))
and some example usage:
Language: typed/racket/base, with debugging; memory limit: 128 MB.
> (add '(1 2 3) '(4 5 6))
- : (Listof Number)
'(5 7 9)
> (add-many '(1 2 3) '(4 5 6) '(7 8 9))
- : (Listof Number)
'(12 15 18)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.