Scala: Как заставить работать конвертирование List[T] с привязкой к контексту?
Это мой первый вопрос, поэтому надеюсь, что я предоставлю достаточно подробностей. Не стесняйтесь просить разъяснений.
Принимая во внимание следующее, который работает:
implicit def optionBsonReader[T, U](implicit ev: BsonReader[T, U]) = new BsonReader[Option[T], Option[U]] {
def read(obj: Option[U]): Option[T] = {
obj match {
case Some(x) => Some(x.fromBson[T])
case None => None
}
}
}
Этот фрагмент кода преобразует упакованные в Option части BSON в другой Option[T]. Я думал, что то же самое будет работать для списков, но следующее не компилируется:
implicit def listBsonReader[T, DBObject](implicit ev: BsonReader[T, DBObject]) = new BsonReader[List[T], MongoCursor] {
def read(cur: MongoCursor): List[T] = {
cur.map(_.fromBson[T]).toList
}
}
Я использую следующий код для общей механики:
package object bson {
def bsonReader[A, B](implicit reader: BsonReader[A, B]) = reader
def bsonWriter[A, B](implicit writer: BsonWriter[A, B]) = writer
implicit def addWriter[A](any: A): WithWriter[A] = new WithWriter(any)
implicit def addReader[A](any: A): WithReader[A] = new WithReader(any)
}
package bson {
private[bson] class WithWriter[A](any: A) {
def toBson[B](implicit writer: BsonWriter[A, B]): B = writer.write(any)
}
private [bson] class WithReader[B](any: B) {
def fromBson[A](implicit reader: BsonReader[A, B]): A = reader.read(any)
}
}
Ошибка компилятора:could not find implicit value for parameter reader: project.marshalling.bson.BsonReader[T,com.mongodb.casbah.Imports.DBObject] cur.map(_.fromBson[T]).toList
Это кажется мне странным, так как кажется, что компилятор пытается оценить T до того, как fromBson был вызван для предоставления типа. Это кажется мне особенно странным, поскольку у читателя опциона, похоже, нет таких жалоб. Я только недавно начал серьезно кодировать в Scala, поэтому я уверен, что что-то здесь не хватает.
Пожалуйста, дайте мне знать, если вам нужна дополнительная информация и надеюсь, что вы можете помочь.
Лучший,
кортик
1 ответ
В вашем listBsonReader нет причины для типа U. Ваш курсор перебирает DBObject, карта ожидает DbObject => X
функция. Я думаю, у вас есть что-то вроде
implicit def withFromBson[U](x: U) = new {
def fromBson[T](implicit ev : BsonReader[T,U]) : T = ...
}
На карте, с _
набранный DBObject
вполне нормально выглядит из BsonReader[T, DBObject]
, Вы не предоставляете ничего в неявном объеме, только BsonReader[T,U]
, Просто удали U
и ваш неявный параметр будет BsonReader[T,DBObject]
,
Компилятор не пытается оценить T
заблаговременно. Он пытается гарантировать, что все T
а также U
может быть на сайте вызова, (в этом случае, U
это проблема), он будет иметь неявное BSonReader[T, DBObject]
это нужно в неявном объеме. Я думаю, что нет ничего в общем окружении. Вы обещаете, с вашим неявным параметром, что вы дадите один BsonReader[T,U]
на сайте вызова. Это не то, что ему нужно. Где параметр неявный (вы должны написать ev при вызове fromBson
), у вас была бы похожая ошибка.