Fetter is a compiler plugin for Scala 2 that brings optional chaining to Scala. It allows you to write code like the following:
trait Person {
val name: String
val parent: Option[Person]
val relatives: List[Person]
}
def foo(person: Option[Person]) = {
val name: Option[String] = person?>name
// desugars to: person.map(_.name)
val parent: Option[Person] = person??>parent
// desugars to: person.flatMap(_.name)
val grandparentName: Option[String] = person??>parent??>parent?>name
// desugars to: person.flatMap(_.parent.flatMap(_.parent.map(_.name)))
}
In fact, it works on any object for which map
and flatMap
are defined:
def getNames(people: List[Person]): List[String] = people?>name
def getRelatives(people: List[Person]): List[Person] = people??>relatives
val loadPerson: IO[Person] = ???
val loadName: IO[String] = loadPerson?>name
In general, the rule is that ?>
desugars to map
, and ??>
desugars to flatMap
.
Optional chaining in a powerful syntactic feature found in some languages, such as Swift, Kotlin, JavaScript, and TypeScript.
In these languages, when selecting from a nullable object, you may use ?.
.
If the object is null, the expression short-circuits and returns null
.
For example, you may write foo?.bar
if foo
is nullable.
If foo
is null, foo?.bar
will be null, but if not, foo?.bar
returns the same as foo.bar
would.
For more information, see:
To use the plugin, first you must add the following external resolver to your `build.sbt``:
externalResolvers += "fetter resolver" at "https://maven.pkg.github.com/liam923/fetter"
Then, add the compiler plugin to the build.sbt
file:
addCompilerPlugin("fetter" %% "fetter" % "1.0.0")