Taking this further, you can define functions of types that specify your desired behaviour exactly, e.g. guess what this does:
foo :: List a -> SortedList a
Or this: bar :: VerificationToken -> Email Unverified -> Email Verified
That's really the main idea. If you specify the types in the right way, you can make them describe the function quite nicely.