I have a 25 kloc Haskell program, and by around 10 kloc I was sure I did't want to need to track down another backtrace-less crash with "head: empty list".
It's imported into every module in my program via a common include which also pulls in other support stuff. Now if I slip up and use head, I get a compile time error as there are two conflicting heads. If I really want to (after all, sometimes you have an invariant) I can use Prelude.head, and I can `git grep Prelude\.` to find all the partial code in my program (currently about 15 occurrences). Or I can read the fine comments in my module for a hint to a non-partial version to use.
There are other approaches, but I've found this to be a fine compromise.
So, I wrote this module: http://source.git-annex.branchable.com/?p=source.git;a=blob;...
It's imported into every module in my program via a common include which also pulls in other support stuff. Now if I slip up and use head, I get a compile time error as there are two conflicting heads. If I really want to (after all, sometimes you have an invariant) I can use Prelude.head, and I can `git grep Prelude\.` to find all the partial code in my program (currently about 15 occurrences). Or I can read the fine comments in my module for a hint to a non-partial version to use.
There are other approaches, but I've found this to be a fine compromise.