[plt-scheme] puzzling bug with (extremely simple) curried Typed Scheme program

From: Benjamin L.Russell (DekuDekuplex at Yahoo.com)
Date: Mon Oct 20 01:32:33 EDT 2008

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



Posted on the users mailing list.