
wc :: String -> (Int, Int, Int) wc file = ( length (lines file) , length (words file) , length file )
Most people tend to think that imperative programming novices don't even start their obvious solutions from something as inefficient as this. Well, I beg to differ. For almost a decade, most (I dare claim even all) Pascal and C compilers were "three-pass" or "two-pass". It means perhaps the compiler reads the input two or three times (each for a different task, just like the above), or perhaps the compiler reads the input once, produces an intermediate form and saves it to disk, then reads the intermediate form from disk, produces a second intermediate form and saves it to disk, then reads the second intermediate form from disk, then it can produce machine code. It must have been the obvious method, since even though it was obviously crappy, everyone was doing it, and "everyone" obviously refers to both novices and gurus. It must also have been pretty non-obvious how to transition from the obvious slow method to a one-pass fast method, since for almost a decade no one did it. Most of us had to wait until someone figured it out and then we had Turbo Pascal. And it was the case with imperative programming.