У меня есть столбец:
val a: Rep[Long] = column[Long]("a")
, который я хочу суммировать:
val b: Rep[Option[Long]] = a.sum
Если нет строк или сумма отрицательна, вернуть 0
в противном случае вернуть sum:
val y: Rep[Long] = b.fold(0) { x => if (x < 0) 0 else x }
Однако этот последний fold
не будет компилироваться, потому что x
- это Rep[Long]
, а не Long
.
Существует неявное преобразование b
на AnyOptionExtensionMethods[Rep[Option[Long]], Rep[Long]]
. Это параметр второго типа Rep[Long]
, вызывающий проблемы. Я хочу, чтобы было Long
. Это явно выглядит так:
val c: LongJdbcType = longColumnType
val d: Shape[FlatShapeLevel, Rep[Long], Long, Rep[Long]] = Shape.repColumnShape[Long, FlatShapeLevel](c)
val e: OptionLift[Rep[Long], Rep[Option[Long]]] = OptionLift.repOptionLift[Rep[Long], Long](d)
val f: AnyOptionExtensionMethods[Rep[Option[Long]], Rep[Long]] = anyOptionExtensionMethods[Long, Rep[Long]](b)(e)
Мне нужно:
val d2: Shape[FlatShapeLevel, Long, Long, Long] = ???
val e2: OptionLift[Long, Rep[Option[Long]]] = OptionLift.anyOptionLift[Long, Long](d2)
val f2: AnyOptionExtensionMethods[Rep[Option[Long]], Long] = anyOptionExtensionMethods[Long, Long](b)(e2)
Что такое d2
? Shape.primitiveShape
- это то, что я ожидал, но должна быть функция OptionLift.constOptionLift
. Итак, теперь я застрял с:
val d3: Shape[FlatShapeLevel, Long, Long, ConstColumn[Long]] = Shape.primitiveShape[Long, FlatShapeLevel]
val e3: OptionLift[Long, Rep[Option[Long]]] = ???
val f3: AnyOptionExtensionMethods[Rep[Option[Long]], Long] = anyOptionExtensionMethods[Long, Long](b)(e3)
Прежде, чем я go продолжу спускаться по кроличьей норе, как это должно работать?
Я почти уверен, что мои намерения использование fold
допустимо. По крайней мере, это то, что соответствует моей интуиции, а также документации:
/** Extension methods for Options of single- and multi-column values */
final class AnyOptionExtensionMethods[O <: Rep[_], P](val r: O) extends AnyVal {
/** Apply `f` to the value inside this Option, if it is non-empty, otherwise return `ifEmpty`. */
def fold[B, BP](ifEmpty: B)(f: P => B)(implicit shape: Shape[FlatShapeLevel, B, _, BP]): BP = {
...
Обновление:
В getOrElse
может быть подсказка, так как в нем происходят некоторые махинации с кастингом :
def getOrElse[M, P2 <: P](default: M)(implicit shape: Shape[FlatShapeLevel, M, _, P2], ol: OptionLift[P2, O]): P =
// P2 != P can only happen if M contains plain values, which pack to ConstColumn instead of Rep.
// Both have the same packedShape (RepShape), so we can safely cast here:
fold[P, P](shape.pack(default): P)(identity)(shape.packedShape.asInstanceOf[Shape[FlatShapeLevel, P, _, P]])
...