I would echo everything Don said and add a few general bits of advice.
For example, two additional tools and libraries you might want to consider:
- QuickCheck for property based testing
- hlint as an extended version of
-Wall
Those are both targeted at code quality.
As a coding practice, avoid Lazy IO. If you need streaming IO, then go with one of the iteratee libraries such as enumerator. If you look on Hackage you'll see libraries like http-enumerator that use an enumerator style for http requests.
As for picking libraries on hackage it can sometimes help to look at how many packages depend on something. Easily see the reverse dependencies of a package you can use this website, which mirrors hackage:
- http://bifunctor.homelinux.net/~roel/hackage/packages/archive/revdeps-list.html
If your application ends up doing tight loops, like a web server handling many requests, laziness can be an issue in the form of space leaks. Often this is a matter of adding strictness annotations in the right places. Profiling, experience, and reading core are the main techniques I know of for combating this sort of thing. The best profiling reference I know of is Chapter 25 of Real-World Haskell.