[plt-scheme] puzzling bug with (extremely simple) curried Typed Scheme program
--- 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
getLine
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.
*Main>
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 )
main.hs:3:14:
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