Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>I have tried to rework your proposal making the collection the Input for the reader, reworking the naming a bit as I went.</p> <pre><code>package monad package object reader{ type UserId = Int } package reader { case class User(id: UserId, name: String, colleagueId: UserId) import com.mongodb.casbah.Imports._ import com.mongodb.casbah trait Reader[I, A] { self =&gt; val run = apply _ def apply(id:I):A def map[B](f: A =&gt; B): Reader[I, B] = new Reader[I, B] { def apply(id: I) = f(self.run(id)) } def flatMap[B](f: A =&gt; Reader[I, B]): Reader[I, B] = new Reader[I, B] { def apply(id: I) = f(self(id)).run(id) } } object Reader { def unit[A](a: =&gt; A) = apply { id: UserId =&gt; a } def apply[I, A](f: I =&gt; A) = new Reader[I, A] { def apply(i: I) = f(i) } } object Users { def asUser(o: DBObject): User = User(o.as[Double]("id").toInt, o.as[String]("name"), o.as[Double]("colleague").toInt) def colleague(u: User): Reader[MongoCollection, User] = Reader{ coll =&gt; asUser(coll.findOne(MongoDBObject("id" -&gt; u.colleagueId)).get) } def getUserById(id:UserId): Reader[MongoCollection, User] = Reader { coll =&gt; asUser(coll.findOne(MongoDBObject("id" -&gt; id)).get) } } object Client extends App { import Users._ def coll: casbah.MongoCollection = MongoClient()("test")("user") // I can do println(getUserById(1)(coll)) // Same with for comprehension val userReader = for (user &lt;- getUserById(1)) yield user println(userReader(coll)) //Combination to explore one-to-one relation val user = getUserById(1)(coll) val otherUser = getUserById(user.colleagueId)(coll) // Same with flatMap println(getUserById(1).flatMap(colleague)(coll)) // Same with for-comprehension but doesn't work val coworkerReader = for {user &lt;- getUserById(1) coworker &lt;- colleague(user)} yield coworker println(coworkerReader(coll)) } } </code></pre> <p>Using this approach I think the code is easier to test as you can pass around the dependency(the MongoCollection) while manipulating only values and functions in your signatures. Read more at <a href="http://blog.originate.com/blog/2013/10/21/reader-monad-for-dependency-injection/" rel="nofollow">http://blog.originate.com/blog/2013/10/21/reader-monad-for-dependency-injection/</a> (I am not the author but it is a clear explanation)</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload