Talvez mais uma reflexão do que um protip, mas o formato funciona.
Quando você reduz o DI ao seu caso degenerado, isso nada mais é do que adicionar um parâmetro a uma função.
Se você levar o processo a um extremo, substituindo quaisquer referências a valores e funções dentro de suas funções por referências a parâmetros que são passados a elas, você irá, por padrão, enviar dependências cada vez mais para cima na pilha de chamadas.
É claro que há maneiras mais eficazes de fazer isso do que encadear manualmente as dependências por meio de várias chamadas de função (como uma mônada do Reader), mas o exercício de pensamento ainda é intrigante.
Ao empurrar as dependências para cima na pilha de chamadas, você chega naturalmente a um ponto em que todas as suas especificações residem nas bordas externas do aplicativo. Esse é o tipo de base de código em que a configuração pode existir basicamente como código, e o comportamento do aplicativo é trivial de modificar de maneiras extremamente granulares e sutis. Este é um tipo muito bom de base de código para trabalhar.
Visto de outro ângulo, a conclusão subjacente pode ser, aumentar a abstração em paralelo com a profundidade da pilha de chamadas geralmente é um sinal de que as coisas estão indo bem.