> Model important things, leave others underspecified so that you can add > logging for example without having to rewrite your program
That's one of the reasons I think the zio/effect is really good. It lets you specify your requirements and errors completely at the type level but you don't have to rewrite your program to change things like adding logging. If you want to add logging (or anything else you might need) deep in your program you provide it as a service via context. Services are usually only provided once at the top of your program and are then usable wherever required. You can switch out the implementation at will for testing or requirements of different environments. It's a "have your cake and eat it too" situation where you get full type safety of errors and requirements but aren't forced to rewrite/restructure things in any major way as the program changes.