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

From: Benjamin L. Russell (dekudekuplex at yahoo.com)
Date: Mon Oct 20 04:33:58 EDT 2008

--- On Mon, 10/20/08, Eli Barzilay <eli at barzilay.org> wrote:

> On Oct 20, Benjamin L.Russell wrote:
> > 
> > #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")))
> You're missing an extra set of parens in the above.

(smack-self-head 'Benjamin)

Aha!  Instead of 

(good-luck-helper-curried name "Good Luck")

, it should have been 

((good-luck-helper-curried name) "Good Luck")

> > (: good-luck-helper-curried (String (String ->
> Void)))
> And here you're missing an arrow:
>   (: good-luck-helper-curried (String -> (String ->
> Void)))

Yep.  I see the problem now.  Instead of 

(: good-luck-helper-curried (String (String -> Void)))

, it should have been 

(: good-luck-helper-curried (String -> (String -> Void)))

> (There is a real problem here: typed-scheme does not
> complain early
> enough about your badly formed type, so the error is
> confusing.  It
> should have said something about not being able to apply
> the `String'
> type.)
> > (define ((good-luck-helper-curried a) b)
> >   (printf "~a, ~a!" a b))

Just for reference, I wrote the following similar Haskell program, and then intentionally made a similar error to see what type of type error message GHCi would generate.  First, here's the correct version of the program, coupled with its output:

module Main where 

mainHelper :: String -> IO String
mainHelper prompt = do
  putStr prompt
main :: IO ()
main = do
  name <- mainHelper "What is your name?  "
  let greeting = "Good Luck"
  if name == "Nobody"
      then putStrLn ("You are " ++ name ++ ".")
      else do putStrLn (greeting ++ ", " ++ name ++ "!")

Prelude> :l main.hs
[1 of 1] Compiling Main             ( main.hs, interpreted )
Ok, modules loaded: Main.
*Main> main
What is your name?  Benjamin
Good Luck, Benjamin!
*Main> main
What is your name?  Nobody
You are Nobody.

Then, I intentionally created a type error by changing the following type annotation:

mainHelper :: String -> IO String

to the following badly formed type annotation:

mainHelper :: String IO String

The error message generated is as follows:

*Main> :l main.hs
[1 of 1] Compiling Main             ( main.hs, interpreted )

    Kind error: `String' is applied to too many type arguments
    In the type `String IO String'
    In the type signature for `mainHelper':
      mainHelper :: String IO String
Failed, modules loaded: none.
Prelude> :e main.hs

For reference, it may be helpful if Typed Scheme were to return a similar type error message in this case.

-- Benjamin L. Russell

Posted on the users mailing list.