This proposal has been implemented in Scala 2.13.0 and Scala 3.0.0.
By: Yang Bo
History
Date | Version |
---|---|
Aug 20th 2018 | Initial Draft |
Motivation
There are three types in Scala to represent a function that accept some of the parameters:
- optional functions:
A => Option[B]
- extracter objects:
{ def unapply(a: A): Option[B] }
and{ def unapplySeq(a: A): Option[Seq[B]] }
- partial fucntions:
PartialFunction[A, B]
Optional functions and partial functions can be converted to each other via PartialFunction.lift
and Function.unlift
. However, there is no simple approach to convert a partial function to an extractor object. As a result, partial functions are not composable. You cannot create a partial function then use it as a pattern in another partial function.
This proposal makes PartialFunction
be an extractor, and provides an unlift
method to convert optional functions to PartialFunction
s.
Motivating Examples
In addition, elementWise
can be used to create an object with a unapplySeq
method, which extracts each element of a sequence data.
Cheat sheet
This proposal allows converting among optional Functions, PartialFunctions and extractor objects as shown in the following table.
How to convert ... | to a partial function | to an optional function | to an extractor |
---|---|---|---|
from a partial function |
partialFunction
|
partialFunction.lift
|
partialFunction
|
from an optional function |
optionalFunction.unlift or Function.unlift(optionalFunction)
|
optionalFunction
|
optionalFunction.unlift
|
from an extractor |
{ case extractor(x) => x }
|
extractor.unapply _
|
extractor
|
Note that optionalFunction.unlift
is preferred to Function.unlift(optionalFunction)
when creating extractors, because only nullary methods are allowed in case
expressions.
Implementation
The idea was originally implemented in a library: Extractor.scala, which has been used in Binding.scala and sbt-api-mappings.
The new implementation aims to become part of core library. The pull request can be found at #7111.