Reader

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

object Reader {

  implicit def readerMonad[E]: Monad[({ type λ[ɑ] = Reader[E,ɑ] })#λ] =
    new Monad[({ type λ[ɑ] = Reader[E,ɑ] })#λ] {

      def pure[A](a: A): Reader[E,A] =
        Reader(_ => a)

      def flatMap[A,B](ma: Reader[E,A])(f: A => Reader[E,B]): Reader[E,B] =
        Reader { e: E =>
          val a: A = ma.run(e)
          f(a).run(e)
        }
    }
}