Live data from Hacker News

Scrap Your Cake Pattern Boilerplate: Dependency Injection Using the Reader Monad

blog.originate.com

11–20 of 20 posts

Re: Scrap Your Cake Pattern Boilerplate: Dependency Injection Using the Reader Monad

#11

Clearest blog post I've read on the Reader monad in Scala. This is something I can see coming to our code base very soon. The next step for us is monad transformers in Scalaz. We are going to end up with something like Future[Reader[Writer[Problem \/ Result]]] (a few type parameters are missing there; hopefully you get the idea). Monad transformers give a way to flatten this stack of monads into a single monad, which…

I've been thinking about using scalaz for a while now. My main concern about the above pattern is the type complexity that will arise. I would love to learn more about monad transformers and how they help out with that issue.

Here's what I've written so far:

https://raw.github.com/noelwelsh/noelwelsh.com/master/_draft...

A bit of searching will find a few talks, blog posts, and Stackoverflow answers. I haven't found anything I really like, which is why I'm writing the post.

Re: Scrap Your Cake Pattern Boilerplate: Dependency Injection Using the Reader Monad

#12

Clearest blog post I've read on the Reader monad in Scala. This is something I can see coming to our code base very soon. The next step for us is monad transformers in Scalaz. We are going to end up with something like Future[Reader[Writer[Problem \/ Result]]] (a few type parameters are missing there; hopefully you get the idea). Monad transformers give a way to flatten this stack of monads into a single monad, which…

I look forward to that blog post. In order to use Scalaz's monad transformers with scala.concurrent.Future, would I have to write my own monad instance for it, or is there a way to re-use the one from scalaz.concurrent?

Re: Scrap Your Cake Pattern Boilerplate: Dependency Injection Using the Reader Monad

#13
post #12

Clearest blog post I've read on the Reader monad in Scala. This is something I can see coming to our code base very soon. The next step for us is monad transformers in Scalaz. We are going to end up with something like Future[Reader[Writer[Problem \/ Result]]] (a few type parameters are missing there; hopefully you get the idea). Monad transformers give a way to flatten this stack of monads into a single monad, which…

I look forward to that blog post. In order to use Scalaz's monad transformers with scala.concurrent.Future, would I have to write my own monad instance for it, or is there a way to re-use the one from scalaz.concurrent?

The scalaz-contrib library has a Monad instance for scala.concurrent.Future: https://github.com/typelevel/scalaz-contrib/blob/master/scal...

Re: Scrap Your Cake Pattern Boilerplate: Dependency Injection Using the Reader Monad

#14
post #12

Clearest blog post I've read on the Reader monad in Scala. This is something I can see coming to our code base very soon. The next step for us is monad transformers in Scalaz. We are going to end up with something like Future[Reader[Writer[Problem \/ Result]]] (a few type parameters are missing there; hopefully you get the idea). Monad transformers give a way to flatten this stack of monads into a single monad, which…

I look forward to that blog post. In order to use Scalaz's monad transformers with scala.concurrent.Future, would I have to write my own monad instance for it, or is there a way to re-use the one from scalaz.concurrent?

A scalaz monad instance for scala.concurrent.Future can be written in about two lines.

Re: Scrap Your Cake Pattern Boilerplate: Dependency Injection Using the Reader Monad

#15
It feels like this isn't actually solving the dependency injection problem - we've moved all our dependencies into this global (ish) Config object, but that object is effectively acting as a service registry. Constructing the Config is still going to require a DI strategy (as the end of the post acknowledges), so what do we actually gain from this reader pattern? I don't think it makes testing any easier (if anything it makes it harder, since we have to build up a whole dummy Config, rather than building a small test cake that only includes the dependencies a specific test needs).

Re: Scrap Your Cake Pattern Boilerplate: Dependency Injection Using the Reader Monad

#16
post #15

It feels like this isn't actually solving the dependency injection problem - we've moved all our dependencies into this global (ish) Config object, but that object is effectively acting as a service registry. Constructing the Config is still going to require a DI strategy (as the end of the post acknowledges), so what do we actually gain from this reader pattern? I don't think it makes testing any easier (if anything…

It does actually solve the problem that DI solves in general, because you create readers that expect the dependency to be injected into them. You still have to decide how to do the injection and that's true for all of the non-framework approaches AFAICT. With the cake pattern you still have to create an object somewhere that mixes in all of the concrete implementations. What you gain from the reader pattern is being able to limit the biolerplate to edge where the injection actually occurs.

As far as having to create a whole dummy Config for testing, that's a fair point, although the reader approach makes it easy to inject it since every reader is a function of the Config. I usually only have a small number of dependencies so it hasn't really been an issue for me. If you're mocking the dependencies each one is only one line of code, and for dependencies you don't need in the you can just use ???.

Re: Scrap Your Cake Pattern Boilerplate: Dependency Injection Using the Reader Monad

#17
I'm not sure I understand the concern regarding the approach using implicits. Sure, you need to add an extra implicit method parameter to each method that requires the dependency, but in the reader approach, every same method needs to be written in the reader monad. In fact, they're really the same concern, since the reader monad instance is just doing the work of threading what would have been implicit in the first place.

Re: Scrap Your Cake Pattern Boilerplate: Dependency Injection Using the Reader Monad

#18
post #17

I'm not sure I understand the concern regarding the approach using implicits. Sure, you need to add an extra implicit method parameter to each method that requires the dependency, but in the reader approach, every same method needs to be written in the reader monad. In fact, they're really the same concern, since the reader monad instance is just doing the work of threading what would have been implicit in the first…

Sorry, now I see it - it enables better type inference. Please ignore :)

Re: Scrap Your Cake Pattern Boilerplate: Dependency Injection Using the Reader Monad

#19
post #18
post #17

I'm not sure I understand the concern regarding the approach using implicits. Sure, you need to add an extra implicit method parameter to each method that requires the dependency, but in the reader approach, every same method needs to be written in the reader monad. In fact, they're really the same concern, since the reader monad instance is just doing the work of threading what would have been implicit in the first…

Sorry, now I see it - it enables better type inference. Please ignore :)

yeah, it is still a similar amount of overhead in typing

Re: Scrap Your Cake Pattern Boilerplate: Dependency Injection Using the Reader Monad

#20
post #19
post #18

Earlier quoted context omitted.

Sorry, now I see it - it enables better type inference. Please ignore :)

yeah, it is still a similar amount of overhead in typing

Actually it's not. Only the primitive readers have similar "overhead" as with the implicits approach. Most of the readers are defined by mapping or flatMapping over the primitives (either explicitly or with comprehensions). With the implicits approach all of the "injected" methods need to declare the dependency via the implicit parameter. With the reader approach, only the primitives have to declare it. Compare the implicits version of UserInfo to the reader version. UserRepository doesn't appear anywhere in the signatures of the reader version.
Post reply on HN