Skip to content

Commit 17dfdbd

Browse files
committed
Write documentation
1 parent d4ba939 commit 17dfdbd

File tree

1 file changed

+47
-0
lines changed

1 file changed

+47
-0
lines changed

docs/_docs/reference/experimental/quoted-patterns-with-polymorphic-functions.md

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,51 @@ title: "Quoted Patterns with Polymorphic Functions"
44
nightlyOf: https://docs.scala-lang.org/scala3/reference/other-new-features/quoted-patterns-with-polymorphic-functions.html
55
---
66

7+
This feature extends the capability of quoted patterns with regard to polymorphic functions. It is not yet part of the Scala language standard. To use this feature, turn on the language feature [`experimental.quotedPatternsWithPolymorphicFunctions`](https://scala-lang.org/api/3.x/scala/runtime/stdLibPatches/language$$experimental$$quotedPatternsWithPolymorphicFunctions$.html). This can be done with a language import
8+
```scala
9+
import scala.language.experimental.quotedPatternsWithPolymorphicFunctions
10+
```
11+
or by setting the command line option `-language:experimental.quotedPatternsWithPolymorphicFunctions`.
712

13+
## Background
14+
Quoted patterns allows us to use quoted code as a pattern. Using quoted patterns, we can check if an expression is equivalent to another, or decompose it. Especially, higher-order patterns are useful when extracting code fraguments inside function bodies.
15+
16+
```scala
17+
def decomposeFunc(x: Expr[Any])(using Quotes): Expr[Int] =
18+
x match
19+
case '{ (a: Int, b: Int) => $y(a, b) : Int } =>
20+
'{ $y(0, 0) }
21+
case _ => Expr(0)
22+
```
23+
24+
In the example above, the first case matches the case where `x` is a function and `y` is bound to the body of the function. The higher-order pattern `$y(a, b)` states that it matches any code with free occurence of variables `a` and `b`. If it is `$y(a)` instead, an expression like `(a: Int, b: Int) => a + b` will not match because `a + b` has an occurence of `b`, which is not included in the higher-order pattern.
25+
26+
## Motivation
27+
This experimental feature extends this higher-order pattern syntax to allow type variables.
28+
29+
```scala
30+
def decomposePoly(x: Expr[Any])(using Quotes): Expr[Int] =
31+
x match
32+
case '{ [A] => (x: List[A]) => $y[A](x) : Int } =>
33+
'{ $y[Int](List(1, 2, 3)) }
34+
case _ => Expr(0)
35+
```
36+
37+
Now we can use a higher-order pattern `$y[A](x)` with type variables. `y` is bound to the body of code with occurences of `A` and `x`, and has the type `[A] => (x: List[A]) => Int`.
38+
39+
## Type Dependency
40+
If a higher-order pattern carries a value parameter with a type that has type parameters defined in the quoted pattern, those type parameters should also be captured in the higher-order pattern. For example, the following pattern will not be typed.
41+
42+
```
43+
case '{ [A] => (x: List[A]) => $y(x) : Int } =>
44+
```
45+
46+
In this case, `x` has the type `List[A]`, which includes a type variable `A` that is defined in the pattern. However, the higher-order pattern `$y(x)` does not have any type parameters. This should be ill-typed. One can always avoid this kind of type errors by adding type parameters, like `$y[A](x)`
47+
48+
## Implementation Restriction
49+
Current implementation only allows type parameters that do not have bounds, because sound typing rules for such pattern is not clear yet.
50+
51+
```scala
52+
case '{ [A] => (x: List[A]) => $y(x) : Int } => // Allowed
53+
case '{ [A <: Int] => (x: List[A]) => $y(x) : Int } => // Disallowed
54+
```

0 commit comments

Comments
 (0)