Struggling with the benefits of the Reader monad

Still struggling with the benefits of the Reader monad… In the well-liked answer on StackOverflow, mergeconflict says

I can explain how Reader works easily: it’s a function, and it takes an argument.

OK, so I think the structure of the technique seems clear: instead of being dependent on some configurable value, it’s preferred to return a function that takes an argument.

This seems to be asserting that :

def foo : Configuration => Unit = { config : Configuration => bar(config) }

is markedly superior to :

def foo(config : Configuration) : Unit = { bar(config) }

? I’m afraid I don’t see the benefit.

The Reader monad is held out as superior to, in particular, DI frameworks, but it seems that :

In contrast, how does Spring (for example) work? …… “we still have to choose” – Sure. In either approach, you have to choose which environment you want to use. That aspect is not magic either way

This seems like begging the question: the “magic” (or at least Reflection) in Spring is a way to deal with the “you have to choose which environment you want to use,” (choosing a type and setting values) aspect not a way to deal with using that environment (acting on those configured values).

If I understand correctly (and it’s clear that something isn’t clicking with me), the Reader monad doesn’t provide a solution to the “choose which environment” task. I think I’d have to write, in source code, something like


val connectionString = System.getenv(“connection_string”)
//or
val connectionString = args[0]
//or
val connectionString = loadFromPropertiesFile(System.getenv(“properties_file”))
/
/*
…etc any of a million ways, of which @Resource annotations might well be considered the most reasonable
*/

I’m really not willfully trying to drag my feet here. I’ve got a real problem where I have 10KLoC of pretty dense code that has hard-coded throughout it some lists that need to be configurable. I really want to do the technique that has the highest quality.

div>