# Dependency Injection in Scala

June 8, 2014

Given a function `run` and a class `Reader` that wraps it:

``````case class Reader[E,A](run: E => A) {

def map[B](g: A => B): Reader[E,B] = ???

}``````

And given a couple of functions with dependencies:

``````val timesTwo: Int => Int = x => x * 2

val plusTwo: Int => Int = x => x + 2``````

Implement `map` and `flatMap` so that we can use `Reader` in a `for`-comprehension:

``````def get(k: String): Reader[Map[String,Int],Int] =

for {
x <- get("x")
a  = timesTwo(x)
y <- get("y")
b  = plusTwo(y)
} yield a * b

println(program.run(Map("x" -> 3, "y" -> 5))) // 42``````

## Bonus

Implement `inject` to automatically lift functions with dependencies into a configuration-specific `Reader`:

``````trait Config {
def x: Int
def y: Int
}

for {
a <- timesTwo.inject(_.x)
b <- plusTwo.inject(_.y)
} yield a * b

println(program2.run(new Config { val x = 3; val y = 5 })) // 42``````

# Solution

Here is one possible solution.
``````case class Reader[E,A](run: E => A) {

def map[B](g: A => B): Reader[E,B] =

}``````

## Bonus

``````implicit class ConfigReader[A,B](val f: A => B) {
def inject(g: Config => A): Reader[Config,B] =
``````\$ curl https://earldouglas.com/exercises/scala-reader.md |