Skip to content

Instantly share code, notes, and snippets.

@LMnet
Last active May 25, 2020 11:27
Show Gist options
  • Save LMnet/0538053e1abd5c45ca3b7204072b036c to your computer and use it in GitHub Desktop.
Save LMnet/0538053e1abd5c45ca3b7204072b036c to your computer and use it in GitHub Desktop.
unNone method on scala 2.13 collections
import scala.collection.generic.IsIterable
import scala.collection.{BuildFrom, IterableOps}
import scala.language.implicitConversions
// Пример для одной конкретной коллекции, рабочий
object ListUtils {
implicit class ListOps[A](val self: List[A]) extends AnyVal {
def unNone[B](implicit ev: A <:< Option[B]): List[B] = {
ev.liftCo(self).collect {
case Some(x) => x
}
}
}
}
// Обобщенный для любой коллекции, у которой есть collect
object CollectionUtils {
class CollectionOps[Repr, I <: IsIterable[Repr]](val coll: Repr, it: I) {
def unNone[B, That](implicit ev: it.A <:< Option[B], bf: BuildFrom[Repr, B, That]): That = {
type F[+A] = IterableOps[A, Iterable, it.C]
val x: F[it.A] = it(coll)
val res = ev.liftCo(x).collect {
case Some(x) => x
}
bf.fromSpecific(coll)(res)
}
}
implicit def toCollectionOps[Repr](coll: Repr)(implicit it: IsIterable[Repr]): CollectionOps[Repr, it.type] =
new CollectionOps(coll, it)
}
object CollectionUtils2 {
// упрощенный вариант от Олега:
implicit class UnNoneOps[F[+x] <: IterableOps[x, F, F[x]], A](private val coll: F[A]) extends AnyVal {
def unNone[B](implicit ev: A <:< Option[B]): F[B] = {
ev.liftCo[F](coll).collect {
case Some(x) => x
}
}
}
}
import CollectionUtils._
val list = List(Some(1), None, Some(2))
val vector = Vector(Some(1), None, Some(2))
list.unNone
vector.unNone
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment