
A lot of programming errors come from failure to correctly validate. I remember being taught to validate on input _and_ validate when you use a value. So I would say do both - use maybe for input functions, and exceptions for when you use a value. You can use the type system to make this more efficient. Imagine you want an integer between 10 and 20, you have a function like: newtype ValidInt = Valid Int validateInt :: Int -> Maybe ValidInt validateInt x | x>=10 && x<=20 = Just (Valid x) validateInt _ = Nothing Now when you validate on input - you produce an error if you get "Nothing" and in all the functions you use the value you use ValidInt instead of Int. This way you use the type system to differentiate between a valid int (does not need to be rechecked) and a normal int (which would need to be validated). Of course you must make sure you don't write more than one constructor function for ValidInt. This suggests a form of constrained constructor would be useful... Whilst this can be done in Haskell, it is not easy and involves reifying the value to a type, and using a type class to constrain the data statement. Really here we are dealing with dependant types, and this is much easier in a dependantly typed language like Epigram. Keean.