Проблемы при использовании Ничего нижнего типа при попытке создать общие нули для параметризованных моноидов

Вот мой код. Он позволяет создавать типы запросов MongoDB с использованием Casbah

trait TypesafeQuery[ObjectType, BuildType] {
 def build: BuildType
}
trait TypesafeMongoQuery[ObjectType] extends TypesafeQuery[ObjectType, DBObject]
case class TypesafeMongoQueryConjunction[ObjectType](queries: Seq[TypesafeMongoQuery[ObjectType]]) extends TypesafeMongoQuery[ObjectType] {
 override def build(): DBObject = $and(queries.map(_.build))
}
case class TypesafeMongoQueryDisjunction[ObjectType](queries: Seq[TypesafeMongoQuery[ObjectType]]) extends TypesafeMongoQuery[ObjectType] {
 override def build(): DBObject = $or(queries.map(_.build))
}
object TypesafeMongoQuery {
 // TODO could probably be reworked? see http://stackoverflow.com/questions/23917459/best-way-to-create-a-mongo-expression-that-never-matches
 val AlwaysMatchingQuery: DBObject = $()
 val NeverMatchingQuery: DBObject = $and($("_id" -> 1), $("_id" -> -1))
 def AlwaysMatchingTypesafeQuery[ObjectType] = new TypesafeMongoQuery[ObjectType] { override def build(): DBObject = AlwaysMatchingQuery }
 def NeverMatchingTypesafeQuery[ObjectType] = new TypesafeMongoQuery[ObjectType] { override def build(): DBObject = NeverMatchingQuery }
 def and[ObjectType](queries: TypesafeMongoQuery[ObjectType]*) = TypesafeMongoQueryConjunction(queries)
 def or[ObjectType](queries: TypesafeMongoQuery[ObjectType]*) = TypesafeMongoQueryDisjunction(queries)
 // TODO maybe define Scalaz Monoids
 def foldAnd[ObjectType](queries: Seq[TypesafeMongoQuery[ObjectType]]) = {
 queries.foldLeft(AlwaysMatchingTypesafeQuery[ObjectType]) { (currentQuery, ***********) =>
 TypesafeMongoQuery.and(currentQuery, ***********)
 }
 }
 def foldOr[ObjectType](base: TypesafeMongoQuery[ObjectType], queries: Seq[TypesafeMongoQuery[ObjectType]]) = {
 queries.foldLeft(NeverMatchingTypesafeQuery[ObjectType]) { (currentQuery, ***********) =>
 TypesafeMongoQuery.or(currentQuery, ***********)
 }
 }
}

Он отлично работает, но я не удовлетворен этими строками:

def AlwaysMatchingTypesafeQuery[ObjectType] = new TypesafeMongoQuery[ObjectType] { override def build(): DBObject = AlwaysMatchingQuery }
 def NeverMatchingTypesafeQuery[ObjectType] = new TypesafeMongoQuery[ObjectType] { override def build(): DBObject = NeverMatchingQuery }

Я думаю, что можно было бы создать новый экземпляр этих двух объектов для каждой операции сгибания, но вместо этого использовать val/singleton типа TypesafeMongoQuery[Nothing], поскольку построенный базовый объект DBObject всегда будет одним и тем же.

Я пробовал кое-что, например, заменять мои подписи повсюду на [ObjectType,T <% ObjectType], но без больших успехов.

Любая идея о том, как решить мою проблему?

1 ответ

Можете ли вы сделать ObjectType ковариант?

trait TypesafeQuery[+ObjectType, BuildType] {
 def build: BuildType
}
trait TypesafeMongoQuery[+ObjectType] extends TypesafeQuery[+ObjectType, DBObject]
object AlwaysMatchingTypesafeQuery extends TypesafeMongoQuery[Nothing] { override def build(): DBObject = AlwaysMatchingQuery }
object NeverMatchingTypesafeQuery extends TypesafeMongoQuery[Nothing] { override def build(): DBObject = NeverMatchingQuery }

licensed under cc by-sa 3.0 with attribution.