diff --git a/core/src/main/scala/besom/internal/Output.scala b/core/src/main/scala/besom/internal/Output.scala index ffb77950..dd4b7dc6 100644 --- a/core/src/main/scala/besom/internal/Output.scala +++ b/core/src/main/scala/besom/internal/Output.scala @@ -114,14 +114,63 @@ trait OutputExtensionsFactory: case b: B => Output(b) } def orElse[B >: A](alternative: => Option[B] | Output[Option[B]])(using ctx: Context): Output[Option[B]] = - output.flatMap { opt => - opt match - case some @ Some(_) => Output(some) - case None => - alternative match - case b: Output[Option[B]] => b - case b: Option[B] => Output(b) + output.flatMap { + case some @ Some(_) => Output(some) + case None => + alternative match + case b: Output[Option[B]] => b + case b: Option[B] => Output(b) } + def mapOption[B: Typeable](f: A => B | Output[B])(using ctx: Context): Output[Option[B]] = + output.flatMap { + case Some(a) => + f(a) match + case b: Output[B @unchecked] => b.map(Some(_)) + case b: B => Output(Some(b)) + case None => Output(None) + } + def flatMapOption[B](f: A => Option[B] | Output[Option[B]])(using ctx: Context): Output[Option[B]] = + output.flatMap { + case Some(a) => + f(a) match + case b: Output[Option[B]] => b + case b: Option[B] => Output(b) + case None => Output(None) + } + + implicit final class OutputListOps[A](output: Output[List[A]]): + def headOption: Output[Option[A]] = output.map(_.headOption) + def lastOption: Output[Option[A]] = output.map(_.lastOption) + def tail: Output[List[A]] = output.map { + case Nil => Nil + case list => list.tail + } + def init: Output[List[A]] = output.map { + case Nil => Nil + case list => list.init + } + def mapList[B](f: A => B): Output[List[B]] = output.map(_.map(f)) + def flatMapList[B](f: A => List[B]): Output[List[B]] = output.map(_.flatMap(f)) + + implicit final class OutputOptionListOps[A](output: Output[Option[List[A]]]): + def headOption: Output[Option[A]] = output.map(_.flatMap(_.headOption)) + def lastOption: Output[Option[A]] = output.map(_.flatMap(_.lastOption)) + def tail: Output[List[A]] = output.map { + case Some(list) => if list.isEmpty then List.empty else list.tail + case None => List.empty + } + def init: Output[List[A]] = output.map { + case Some(list) => if list.isEmpty then List.empty else list.init + case None => List.empty + } + def mapList[B](f: A => B): Output[List[B]] = output.map { + case Some(list) => list.map(f) + case None => List.empty + } + def flatMapList[B](f: A => List[B]): Output[List[B]] = output.map { + case Some(list) => list.flatMap(f) + case None => List.empty + } end OutputExtensionsFactory object Output: