imaginary family values presents
a blog that reclines to the left
One reason I haven’t been doing much blogging recently is that I’ve been spending a lot of time learning Haskell, a computer language with a number of intriguing features. Since I have previously remarked on weaknesses in Java’s type system, I thought I would start by remarking on Haskell’s type inference. Unlike many of the language’s other intriguing features, this one is easy to demonstrate and its benefits are easy to explain.
Consider this Haskell program:
main = do str <- getLine let n = read str putStr "Twice that is " putStrLn (show (n * 2.0))
Like C, C++, and Java, Haskell is statically typed: every variable has a type that is known at compile time. Unlike those other languages, though, you don’t have to explicitly declare the type of a variable when the compiler can figure it out. The compiler knows that str
is a string, because that’s what the standard library function getLine
returns1. The read
function is polymorphic and can translate a string into any of a wide variety of Haskell types, but the compiler can still figure out the type of n
, because it shows up later as an argument to *
; since 2.0 is a floating-point number, then n
must be one as well.
sethg@henbane:~/Desktop/hs$ ./a.out 3.5 Twice that is 7.0 sethg@henbane:~/Desktop/hs$ ./a.out 42 Twice that is 84.0 sethg@henbane:~/Desktop/hs$ ./a.out 0x10 Twice that is 32.0 sethg@henbane:~/Desktop/hs$ ./a.out fred Twice that is a.out: Prelude.read: no parse
I realize that programmers get into fervent religious wars over the question of static vs. dynamic typing, but I think I can avoid getting roasted by either side if I point out that if you have to use a statically typed language, it would be nice to use one with type inference. Why should we humans have to keep track of those tedious details if the computer can do it for us?
PS: Notice how in the code, the read
function appears before the call to print the phrase Twice that is
, but in the output of the running program, the error message from read
appears after that phrase. That’s lazy evaluation, another intriguing Haskell feature….
1 Actually, getLine
is type IO String
. Explaining how the output of this function gets bound to a variable of type String
would require explaining Haskell’s monadic IO system, which I’m not ready to do just yet.