Да, это потому, что вы используете разные типы монад для понимания.
Подумайте о ненасыщенной версии.Scala для понимания сводится к серии вызовов map
и flatMap
.Тип flatMap
определяется по существу следующим образом:
def flatMap[F[_], A, B](item: F[A])(fn: A => F[B]): F[B]
Обратите внимание, что при изменении внутреннего типа тип обертки всегда имеет один и тот же тип F. Здесь вы смешиваете тип эффекта DBIOс опцией в том же для понимания - это нарушает определение flatMap.
В вашем случае, если вы хотите сохранить все это в понимании for
, вы можете попробовать монаду OptionT
Трансформатор от Cats: https://typelevel.org/cats/datatypes/optiont.html. OptionT
, по сути, предоставляет оболочку, которая позволяет обрабатывать монадическое значение F[Option[_]]
как монадическое значение само по себе.Обратите внимание, что у вас также есть список, который является третьим монадическим типом.Таким образом, ваши вычисления могут выглядеть следующим образом:
import cats._
import cats.data._
import cats.implicits._
val movieTicketSaleNumbers: List[MovieTicketSale] = cinemaApi.allMovieTicketSales
def insertTicket(sale: MovieTicketSale): OptionT[DBIO, UUID] =
for {
movie <- OptionT(moviesDb.findOneExact(sale.movie.id))
movieNumberDbId <- OptionT.liftF(insertMovieTicketSale(sale, movie))
} yield movieNumberDbId
val insertMetricActions: List[DBIO[Option[UUID]]] = movieTicketSaleNumbers.map(insertTicket(_).value)
Это даст вам список эффектов, обертывающих необязательные UUID, которые были вставлены.
Для этого вам не нужны Cats, хотя,Вы можете делать то, что хотите, в ванильном Scala, хотя это немного сложнее:
val movieTicketSaleNumbers: List[MovieTicketSale] = cinemaApi.allMovieTicketSales
def insertTicket(sale: MovieTicketSale): DBIO[Option[UUID]] =
for {
movie <- moviesDb.findOneExact(sale.movie.id)
movieNumberDbId <- movie.map(insertMovieTicketSale(sale, _).map(Option(_))).getOrElse(DBIO.successful(None))
} yield movieNumberDbId
val insertMetricActions: List[DBIO[Option[UUID]]] = movieTicketSaleNumbers.map(insertTicket(_))
Вероятно, есть более элегантный способ выразить это, особенно преобразование Option[DBIO[UUID]]
в DBIO[Option[UUID]]
.
Надеюсь, это поможет!