Last active
May 25, 2020 11:27
-
-
Save LMnet/0538053e1abd5c45ca3b7204072b036c to your computer and use it in GitHub Desktop.
unNone method on scala 2.13 collections
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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