[plt-scheme] Typed scheme and curry
The "curry" function in Typed Scheme isn't just about writing curried
functions, it's about converting uncurried functions to curried
functions. If you want to write a function in a curried style from
the get-go, you can do it like this:
#lang typed-scheme
(: curried (Integer -> (String -> (Char -> Boolean))))
(define (((curried n) s) c)
(and (<= 0 n (- (string-length s) 1))
(equal? (string-ref s n) c)))
And you can then use it like this:
> curried
- : (Integer -> (String -> (Char -> Boolean)))
#<procedure:curried>
> ((curried 5) "PLT Scheme")
- : (Char -> Boolean)
#<procedure>
If, however, you have an uncurried function and want to convert it to
a curried function, you're just as out of luck in Haskell or ML as you
are in Typed Scheme. Given a function of type (a,b,c,d) -> int,
there's no builtin Haskell or ML function to produce a function of
type a -> b -> c -> d -> int. You could write one, but it would not
generalize to (a,b,c,d,e).
The "curry" function in scheme/function does, in the case where
dynamic arity checks produce meaningful results, generalize like that.
Unfortunately, we have no way of writing down its most general type
(nor do most other type systems), and its dynamic arity checks do not
always tell the whole story.
So, what you've run into is partially a quirk of the "curry" function
and partially a problem that is hard in a statically typed world.
--Carl
On Fri, Dec 19, 2008 at 6:03 PM, Scott McLoughlin <scott at adrenaline.com> wrote:
> FWIW, strongly typed languages like Haskell and ML have curried functions.
> The typing
> isn't very complicated at all.
>
> fun fubar (a : Int) (b : Str) (c : Dbl) : Str = blah blah blah;
>
> fubar 1;
> => fn(Str, Dbl): Str
>
> k = fubar 1 "Hello";
> => k : fn(Dbl) : Str
>
> k 3.4;
> => _ : "1 Hello 3.4"
>
> Or whatever depending upon the function definition. Point is that currying
> loses no type information.
>
> Scott