The point of typing is that types <i>are</i> tests: they ensure logical consistency of your program, and they are checked by the compiler. This has a number of consequences.<p>- Some error conditions are inexpressible in your program. You cannot write classical tests to verify these, as trying to recreate the erroneous conditions will result in type errors.<p>- You cannot forget to &quot;write a type&quot; like you can forget to write a test. A type always covers all the guarantees it makes. This is especially useful when there are no tests, as you have at least some kind of helper available to you.<p>- Types are a form of documentation. Again, even a poorly documented, poorly named project still has types.<p>- Types do not make tests obsolete, but they greatly reduce the number of them you have to write and maintain.<p>As a result of this, most Haskell projects have <i>abysmal</i> test coverage compared to what you&#x27;d expect in Python or Java. Nobody would (or could!) write tests that all &quot;instanceof&quot; checks are covered. When you forget to implement a branch in your program, you&#x27;ll get a compilation warning. When you feed a value to a well-written function, you&#x27;re guaranteed to get a non-nonsense result out of it (instead of an exception). But still, you can make core changes to programs you do not understand at all - while understanding the type system in general - and have your changes work as expected.