0

As you know casbah mongodb driver has an update function like this :

def update [A, B] (q: A, o: B)(implicit arg0: (A) ⇒ DBObject, arg1: (B) ⇒ DBObject) : WriteResult

I think i understand currying concept of scala. However, As far as I know this update function is supposed to be used like this :

collection.update(MongoDBObject(...), MongoDBObject(...))

This confuses me. As I do not fill second argument list of the update method, I would think above expression would return a function like :

(implicit arg0: (A) ⇒ DBObject, arg1: (B) ⇒ DBObject) => WriteResult

However it does not. Is it because of the implicit definiton for the arguments in the second function argument list ?

  • If you have an implicit value of type `A => DBObject` and an implicit value of `B => DBObject` in scope, then those values are applied when calling `update`. Though, if you want to only partially apply the function, you should be able to do so by calling `collection.update(MongoDBObject(...), ...) _` (appending an underscore) – Kulu Limpa Jun 12 '15 at 21:30
  • I dont understand how it is in the scope though. I guess I would need to see the source code underneath the implementation of currying, to fully understand that it is indeed in the scope. I am having hard time understanding when something is in the scope or not – Özüm Safaoğlu Jun 12 '15 at 21:40
  • I don't know casbah, so I probably can't help you. However, this is less about currying than it is about implicits. Looks like in this case currying is only needed to allow adding implicit arguments (because you can't specify e.g., `def f(a: int, implicit b: Int)` but only `def f(a: Int)(implicit b: Int)` for some reason) Maybe you can update the question to include all your imports, so one may be able to figure out where the implicits are in scope. – Kulu Limpa Jun 12 '15 at 21:49
  • But isnt the second argument list hence, being provided from the first argument list in this case? – Özüm Safaoğlu Jun 12 '15 at 22:09
  • Type inference will determine the generic type `A` and `B` based on the first argument list, but other than that, the first argument list does not impact the second. My guess is that something you imported has an `implicit def f(x: MongoDBObject): DBObject` defined. – Kulu Limpa Jun 12 '15 at 22:13

1 Answers1

0

The Casbah library subscribes to the "pimp my library" pattern. It extends the official MongoDB Java driver and adds implicits and other functionality to make using the Java driver feel "native" in scala.

The update method looks like this:

  /**
   * Performs an update operation.
   * @param q search query for old object to update
   * @param o object with which to update <tt>q</tt>
   */
  def update[A, B](q: A, o: B, upsert: Boolean = false, multi: Boolean = false,concern: com.mongodb.WriteConcern = this.writeConcern
this.writeConcern)(implicit queryView: A => DBObject,
                            objView: B => DBObject,
                            encoder: DBEncoder = customEncoderFactory.map(_.create).orNull): WriteResult = {
    underlying.update(queryView(q), objView(o), upsert, multi, concern, encoder)
}

The Java driver requires DBObject for its update operation, but Casbah provides a Scala helper for creating DBObjects in MongoDBObject. To provide interop between the Scala types and the Java type we can make use of implicit parameters.

As the compiler will know A at compile time, it can determine whether an implicit definition of type A => DBObject is in scope. Casbah then uses that method queryView(q) which converts q to DBObject and passes it to the underlying update.

Ross
  • 17,861
  • 2
  • 55
  • 73