Если вы посмотрите на определение cats.data.Writer
, вы увидите, что это псевдоним cats.data.WriterT
с фиксированным эффектом Id
.
Что вы хотите сделать, так это использовать WriterT
напрямую, а вместо Id
использовать OptionT[Try, YourType]
.
Вот небольшой пример кода того, как этого можно добиться:
object Example {
import cats.data._
import cats.implicits._
type MyType[A] = OptionT[Try, A]
def myFunction: MyType[Int] = OptionT(Try(Option(1)))
def main(args: Array[String]): Unit = {
val tmp: WriterT[MyType, List[String], Int] = for {
_ <- WriterT.tell[MyType, List[String]](List("Before first invocation"))
i <- WriterT.liftF[MyType, List[String], Int](myFunction)
_ <- WriterT.tell[MyType, List[String]](List("After second invocation"))
j <- WriterT.liftF[MyType, List[String], Int](myFunction)
_ <- WriterT.tell[MyType, List[String]](List(s"Result is ${i + j}"))
} yield i + j
val result: Try[Option[(List[String], Int)]] = tmp.run.value
println(result)
// Success(Some((List(Before first invocation, After second invocation, Result is 2),2)))
}
}
Аннотации типов делают это немного уродливым, но в зависимости от вашего варианта использования вы можете избавиться от них. Как видите, myFunction
возвращает результат типа OptionT[Try, Int]
, а WriterT.lift
поместит его в объект записи, который также имеет List[String]
для ваших журналов.
person
Denis Rosca
schedule
31.07.2018