-
-
Save fancellu/985bbba473d238043f458c00228336bf to your computer and use it in GitHub Desktop.
import scala.annotation.targetName | |
import scala.util.boundary | |
import scala.util.boundary.{Label, break} | |
// Works in Scala 3.4.1 | |
def firstIndex[T](xs: List[T], p: T): Int = { | |
boundary: | |
for (x, i) <- xs.zipWithIndex do if (x == p) break(i) | |
-1 | |
} | |
object optional: | |
inline def apply[T](inline body: Label[None.type] ?=> T): Option[T] = boundary(Some(body)) | |
extension [T](r: Option[T]) | |
@targetName("?") | |
inline def ?(using label: Label[None.type]): T = r.getOrElse(break(None)) | |
def firstColumn[T](xss: List[List[T]]): Option[List[T]] = | |
optional: | |
xss.map(_.headOption.?) | |
@main | |
def main(): Unit = { | |
val li = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) | |
println(firstIndex(li, 5)) | |
val listOfList = List(li, List(99, 100)) | |
println(firstColumn(listOfList)) | |
val listOfList2 = List(li, Nil) | |
println(firstColumn(listOfList2)) | |
} |
How'd you use it to implement traverse
on a list of Either
? In other words, return the first left, or combine all the rights.
How'd you use it to implement
traverse
on a list ofEither
? In other words, return the first left, or combine all the rights.
def firstLeftOrAllRights[A, B](eithers: List[Either[A, B]]): Either[A, List[B]] = {
eithers.partition(.isLeft) match {
case (lefts, rights) => lefts.headOption.map(Left()).getOrElse(Right(rights.map(_.right.get)))
}
}
or
def firstLeftOrAllRights[A, B](eithers: List[Either[A, B]]): Either[A, List[B]] = {
eithers.find(.isLeft) match {
case Some(Left(a)) => Left(a)
case _ => Right(eithers.filter(.isRight).map(_.right.get).toList)
}
}
I meant fail-fast, which is the whole point of break
. I found a related discussion here.
Outputs
4
Some(List(1, 99))
None