I can write a simple function in untyped Racket called curry-all
that takes a list of functions, all of which accept the same kind of value for their first argument, and produces a list of functions with their first arguments curried.
(define (curry-all fs arg)
(map (λ (f) (curry f arg)) fs))
For a running example of the above function, see this snippet on pasterack.
This is a valid function, but I'm not sure if it's even possible to type in Typed Racket given its polymorphic typing constructs. The type of curry
itself is already fairly complex, and obviously the type of curry-all
would need to be necessarily more complex.
I made a relatively simple attempt at typing this function, though I was quite aware that it would not function as I liked:
(: curry-all
(All [a c b ...]
(Listof (-> a b ... b c)) a
-> (Listof (-> b ... b c))))
(define (curry-all fs arg)
(map (λ ([f : (-> a b ... b c)])
(curry f arg))
fs))
Obviously, this works if all the functions have identical types (which isn’t worthless!), but it fails if they have different arities, even if their first arguments’ types are shared.
Is there any way to specify this function’s type so that it will work in a more general case?
require/typed
to import code from untyped code. No contracts are applied to values used within typed code, since the typechecker guarantees soundness. As you note, though, many polymorphic types can't be converted to contracts, so you're correct that this would not be usable from untyped code. – Timeprocedure-arity
and the implementation ofcurryr
uses it. That code may be modifiable to provide the required implementation of amy-curry
to do what you want. – Acetifymap
? – Flamen