
The Haskell type system is simply not rich enough to guarantee everything you might need.
That's true, and after giving this a bit more thought, I realized it's not JUST the type system that I'm talking about here. There are a few other features that make it hard for me to want to use unit/property tests. For example, say (for the sake of simplicity and familiarity) that I'm writing the foldl function. If I were writing this function in any other language, this would be my process: first I'd write a test to check that foldl returns the original accumulator when the list is empty. Then I would write code until the test passed. Then I would move on to the next property of foldl and write a test for it. Rinse repeat. But in Haskell, I would just write the code:
foldl _ acc [] = acc
The function is obviously correct for my (missing) test. So I move on to the next parts of the function:
foldl _ acc [] = acc foldl f acc (x:xs) = foldl f (f acc x) xs
and this is equally obviously correct. I can't think of a test that would increase my confidence in this code. I might drop into the ghci repl to manually test it once, but not a full unit test. I said that writing Haskell code feels like "writing code against a solid test base." But I think there's more to it than this. Writing Haskell code feels like writing unit tests and letting the machine generate the actual code from those tests. Declarative code for the win. Despite all this, I suspect that since Haskell is at a higher level of abstraction than other languages, the tests in Haskell must be at a correspondingly higher level than the tests in other languages. I can see that such tests would give great benefits to the development process. I am convinced that I should try to write such tests. But I still think that Haskell makes a huge class of tests unnecessary.
Haskell has some awesome testing tool, and I highly recommend getting acquainted with them.
I will certainly take your advice here. Like I said, I use TDD in other languages but mysteriously don't feel its absence in Haskell. I probably need to get into better habits. --Jonathan