Skip to content

Instantly share code, notes, and snippets.

@fancellu
Created April 25, 2024 17:52
Show Gist options
  • Save fancellu/985bbba473d238043f458c00228336bf to your computer and use it in GitHub Desktop.
Save fancellu/985bbba473d238043f458c00228336bf to your computer and use it in GitHub Desktop.
Scala3 boundary/break/label demo (uses Scala 3.4.1)
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))
}
@fancellu
Copy link
Author

Outputs

4
Some(List(1, 99))
None

@asarkar
Copy link

asarkar commented Aug 21, 2024

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.

@fancellu
Copy link
Author

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.

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)
}
}

@asarkar
Copy link

asarkar commented Aug 21, 2024

I meant fail-fast, which is the whole point of break. I found a related discussion here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment