[plt-scheme] puzzling bug with (extremely simple) curried Typed Scheme program
Just for fun, I decided to try currying a very simple Typed Scheme
program to wish the user good luck, using the person's name supplied
as an argument to the function. The uncurried version works; the
curried one doesn't; I have no idea why.
Here's the uncurried Typed Scheme version, which works:
#lang typed-scheme
(: good-luck-typed (String -> Void))
(define (good-luck-typed name)
(if (string=? name "Nobody")
(printf "You are ~a." name)
(good-luck-helper-typed name "Good Luck")))
(: good-luck-helper-typed (String String -> Void))
(define (good-luck-helper-typed a b)
(printf "~a, ~a!" a b))
Here's a sample session using this program:
Welcome to DrScheme, version 4.1.1 [3m].
Language: Module.
> (good-luck-typed "Benjamin")
Benjamin, Good Luck!
> (good-luck-typed "Nobody")
You are Nobody.
>
So far, so good. But then the following curried version generates a
bug, as follows:
#lang typed-scheme
(: good-luck-curried (String -> Void))
(define (good-luck-curried name)
(if (string=? name "Nobody")
(printf "You are ~a." name)
(good-luck-helper-curried name "Good Luck")))
(: good-luck-helper-curried (String (String -> Void)))
(define ((good-luck-helper-curried a) b)
(printf "~a, ~a!" a b))
Here's the error generated when I try to run the program:
Welcome to DrScheme, version 4.1.1 [3m].
Language: Module.
. typecheck: untyped var: a in: a
>
The term "a" in the definition "((good-luck-helper-curried a) b)" is
then highlighted in pink.
Apparently, Scheme seems unable to understand that 'a' is of type
String, even though I have already supplied a type annotation
documenting this type.
However, this syntax seems correct, considering the following
uncurried and curried versions of hanoi, which I had created earlier:
Uncurried Typed Scheme version of hanoi, followed by sample output:
#lang typed-scheme
(: hanoi-typed (Number -> Void))
(define (hanoi-typed n)
(hanoi-helper-typed 'A 'B 'C n))
(: hanoi-helper-typed (Symbol Symbol Symbol Number -> Void))
(define (hanoi-helper-typed source using destination n)
(cond ((= n 1)
(printf "Moving from disc ~a to ~a.\n" source destination))
(else
(hanoi-helper-typed source destination using (- n 1))
(hanoi-helper-typed source using destination 1)
(hanoi-helper-typed using source destination (- n 1)))))
Welcome to DrScheme, version 4.1.1 [3m].
Language: Module.
> (hanoi-typed 3)
Moving from disc A to C.
Moving from disc A to B.
Moving from disc C to B.
Moving from disc A to C.
Moving from disc B to A.
Moving from disc B to C.
Moving from disc A to C.
>
Curried Typed Scheme version of hanoi, followed by sample output:
#lang typed-scheme
(: hanoi-curried (Number -> Void))
(define (hanoi-curried n)
((((hanoi-helper-curried 'A) 'B) 'C) n))
(: hanoi-helper-curried (Symbol -> (Symbol -> (Symbol -> (Number ->
Void)))))
(define ((((hanoi-helper-curried source) using) destination) n)
(cond ((= n 1)
(printf "Moving from disc ~a to ~a.\n" source destination))
(else
((((hanoi-helper-curried source) destination) using) (- n 1))
((((hanoi-helper-curried source) using) destination) 1)
((((hanoi-helper-curried using) source) destination) (- n
1)))))
Welcome to DrScheme, version 4.1.1 [3m].
Language: Module.
> (hanoi-curried 3)
Moving from disc A to C.
Moving from disc A to B.
Moving from disc C to B.
Moving from disc A to C.
Moving from disc B to A.
Moving from disc B to C.
Moving from disc A to C.
>
Am I missing something terribly elementary, or is there some other
reason for the above-mentioned apparent bug? I can't understand the
reason that while Scheme can understand that "source" is of type
Symbol using the type annotation for hanoi-helper-curred above, it
cannot understand that 'a' is of type String in the type annotation
for good-luck-helper-curried previously
-- Benjamin L. Russell