Question

I try to implement this answer and I encounter a compilation error :

def $match(o: DBObject) = MongoDBObject("$match" -> o)

def getObj(instance   : String,                   contextValue: Option[SpaceId]           = None,
            eventType  : Option[String]    = None,
           sourceValue: Option[Long]      = None, targetValues: Option[Iterable[Long]] = None,
           startDate  : Option[LocalDate] = None, endDate     : Option[LocalDate]      = None) : DBObject = {

…  
}

def getMatchObj = (getObj _).map($match)

And the error is :

[info] Compiling 1 Scala source to /mnt/data/backup/dev/projects/bluekarma/bluekarma-  analytics-scala-play2/target/scala-2.10/classes...
[error] /mnt/data/backup/dev/projects/bluekarma/bluekarma-analytics-scala-play2/app/models/Dao.scala:121: Unable to unapply type `(String, Option[modelsIds.SpaceId],   Option[String], Option[Long], Option[Iterable[Long]], Option[org.joda.time.LocalDate], Option[org.joda.time.LocalDate]) => com.mongodb.casbah.query.Imports.DBObject` into a type constructor of kind `M[_]` that is classified by the type class `scalaz.Functor`
[error] 1) Check that the type class is defined by compiling `implicitly[scalaz.Functor[<type constructor>]]`.
[error] 2) Review the implicits in object Unapply, which only cover common type 'shapes'
[error] (implicit not found: scalaz.Unapply[scalaz.Functor, (String, Option[modelsIds.SpaceId], Option[String], Option[Long], Option[Iterable[Long]], Option[org.joda.time.LocalDate], Option[org.joda.time.LocalDate]) => com.mongodb.casbah.query.Imports.DBObject])
[error]   def getMatchObj = (getObj _).map($match)
[error]                      ^
[error] one error found
[error] (compile:compile) Compilation failed
[error] Total time: 3 s, completed Feb 6, 2014 9:53:13 AM
Was it helpful?

Solution

I guess it's a problem with scala compiler: it can't use Function7[...., T] as M[T].

You could help to compiler this way:

type MF7[T] = (String, Option[SpaceId], Option[String], Option[Long], Option[Iterable[Long]], Option[LocalDate],  Option[LocalDate]) => T

(getObj _: MF7[DBObject]).map(myMatch)

Note that you should avoid $ in names. $ is widely used in scala for generated names.

map works for Function6, so you could just reduce parameters cont. For instance you could group parameters using case class:

case class Period(startDate: Option[LocalDate] = None, endDate: Option[LocalDate] = None)

def getObj(instance: String, contextValue: Option[SpaceId] = None,
           eventType: Option[String] = None, sourceValue: Option[Long] = None,
           targetValues: Option[Iterable[Long]] = None,
           period: Option[Period] = None) : DBObject = ???

val getMatchObj = (getObj _).map(myMatch)

shapeless

With shapeless you could convert function of any arity to function of single HList argument and vice versa:

val getMatchObj = (getObj _).toProduct.andThen(myMatch).fromProduct

Default parameters

scala functions can't have default parameters, so the only way to preserve default parameters is to extract all parameters to case class like this:

case class GetObjArgs(instance: String, contextValue: Option[SpaceId] = None,
               eventType: Option[String] = None, sourceValue: Option[Long] = None,
               targetValues: Option[Iterable[Long]] = None,
               startDate: Option[LocalDate] = None, endDate: Option[LocalDate] = None)

def getObj(a: GetObjArgs): DBObject = ???

val getMatchObj = (getObj _) andThen myMatch

getMatchObj(GetObjArgs("inst", sourceValue = Some(1)))
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top