Read The False Hope of Managing Effects with Tagless-Final in Scala – John A De Goes. Some thoughts.
Tagless Final was initially designed for the purpose of embedding a language, and providing various implementations of that language. That is the most flexibility you can get without designing a new parser. To think this places any restraints on the programmer is a big misunderstanding.
Being able to substitute the implementation entirely may be a curse more than a blessing. It gives no guarantee as to what a piece of code means. Again, the original purpose was to embed a language, so that flexibility is a feature. Programming in this style is basically programming an interpreter or a compiler for an almost entirely new language.
But, for most purposes, it is rare that you can design a better language than the ones polished by many people over years. Just use them instead.