Next: Metals NotesUp: Scala

Hax

Table of Contents

Scala LyfHax.

1 Unapplying a String Interpolator

Since 2.13 you can use unapply with string interpolators:

"0 13 * * * echo 'Every day at 1pm'" match {
  case s"$min $hour $dayOfMonth $month $dayOfWeek $cmd" => Some(cmd)
  case _                                                => None
}
// Option[String] = Some("echo 'Every day at 1pm'")

2 null to Option

We can easily turn possible null values into an Option via apply:

val myString: String = null
Option(myString)
// Option[String] = None

Note without the type hint here the Option will have type Option[Null].

3 Apply on Different Data Structures

3.1 Lists

We can use the apply method on List objects to obtain the value at an index, but beware this is not safe, lift is usually a better option.

val myList = List(1, 2, 3)
myList(1)
// 2
myList(3)
// java.lang.IndexOutOfBoundsException: 3
//   scala.collection.LinearSeqOps.apply(LinearSeq.scala:117)
//   scala.collection.LinearSeqOps.apply$(LinearSeq.scala:114)
//   scala.collection.immutable.List.apply(List.scala:79)

apply on Maps, Strings, Arrays, Ranges, Vectors and Seqs behaves similarly.

3.2 Sets

apply on Sets can be used to test membership:

val bellsLt1k = Set(1, 2, 5, 15, 52, 203, 877)
bellsLt1k(203)
// true
bellsLt1k(10)
// false

4 For Comprehension One-liner

val rollOfTwoDie = (for (x <- (1 to 6); y <- (1 to 6)) yield x + y).sorted
// Vector(2, 3, 3, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 9, 9, 9, 9, 10, 10, 10, 11, 11, 12)

5 Tuple to Case Class

We can use the .tupled method of FunctionN to nicely obtain a case class instance from a tuple:

case class Book(title: String, author: String)

val bookData = ("Old Man's War", "John Scalzi")
// Pre Scala 2.11.8
val book1 = (Book.apply _).tupled(bookData)
// The companion object of case class extends FunctionN so we can do this is 2.11.8+
val book2 = Book.tupled(bookData)

6 Quicksort

Obligatory quicksort implementation:

import scala.math.Ordering.Implicits._

def quicksort[A: Ordering](l: List[A]): List[A] = {
  l match {
    case Nil => Nil
    case head :: tail =>
      val (before, after) = tail.partition(_ <= head)
      (before :+ head) ::: after
  }
}

7 Capturing Standard Output

You can easily capture standard output using Console.withOut. This saves you from having to reset the output stream when you're done if you were to use System.setOut.

val baos = new java.io.ByteArrayOutputStream()
// Note println is an alias for Console.println
Console.withOut(baos)(println("hello"))
println(baos)
// "hello"

Author: root

Created: 2024-03-23 Sat 11:44

Validate