0

I am trying to write a function that reads from a repository (which returns F[Option[Entry]] where F is a future) and then converts it to F[Option[Element]]. The function convert() takes a Seq[Entry] and returns ValidatedNel[LoadError, Seq[Element]]. I am trying to do this with for comprehensions however my issue is that the function returns F[Opt[F[Seq[Element]]]] instead of F[Opt[Element]]. What am I doing wrong? Any help would be great!

Note: ValidatedNel is a cats datatype

override def findByPath(key: String)(
  implicit ME: MonadError[F, Throwable]
): F[Option[Element]] = {
  val result = for {
    optionEntry <- repo.findByKey(key)
  } yield for {
    entry <- optionEntry
    elements = convert(Seq(entry))
  } yield elements.fold(
    reason => ME.raiseError[Seq[Element]](ClientError(reason)),
    ME.pure
  )
  result
}
Dmytro Mitin
  • 48,194
  • 3
  • 28
  • 66
Chris Johnston
  • 335
  • 1
  • 2
  • 16

1 Answers1

2

Try to use monad transformer OptionT and unpack head of Element sequence (since you pack a single Entry into sequence)

override def findByPath(key: String)(
  implicit ME: MonadError[F, Throwable]
): F[Option[Element]] = {
  val result = for {
    entry <- OptionT(repo.findByKey(key))
    elements = convert(Seq(entry))
    res <- OptionT.liftF(elements.fold(
      reason => ME.raiseError[Element](ClientError(reason)),
      elems => ME.pure(elems.head)
    ))
  } yield res

  result.value
}
Dmytro Mitin
  • 48,194
  • 3
  • 28
  • 66