Skip to content

Commit 9c16980

Browse files
committed
Document this functionality
1 parent a6f2332 commit 9c16980

File tree

1 file changed

+29
-0
lines changed

1 file changed

+29
-0
lines changed

docs/docs/reference/contextual/givens.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,35 @@ instance named `ctx` is established by matching against the first half of the `p
105105

106106
In each case, a pattern-bound given instance consists of `given` and a type `T`. The pattern matches exactly the same selectors as the type ascription pattern `_: T`.
107107

108+
## Negated Givens
109+
110+
Scala 2's somewhat puzzling behavior with respect to ambiguity has been exploited to implement the analogue of a "negated" search in implicit resolution, where a query Q1 fails if some other query Q2 succeeds and Q1 succeeds if Q2 fails. With the new cleaned up behavior these techniques no longer work. But there is now a new special type `scala.util.NotGiven` which implements negation directly.
111+
112+
For any query type Q: NotGiven[Q] succeeds if and only if the implicit search for Q fails. Example:
113+
114+
```scala
115+
116+
import scala.util.NotGiven
117+
118+
trait Tagged[A]
119+
120+
case class Foo[A](value: Boolean)
121+
trait FooLowPrio {
122+
implicit def fooDefault[A]: Foo[A] = Foo(true)
123+
}
124+
object Foo extends FooLowPrio {
125+
implicit def fooNotTagged[A](implicit ev: NotGiven[Tagged[A]]): Foo[A] = Foo(false)
126+
}
127+
128+
@main def main() =
129+
implicit val taggedInt: Tagged[Int] = null
130+
131+
assert(implicitly[Foo[Int]].value) // fooDefault
132+
133+
assert(!implicitly[Foo[String]].value) // fooNotTagged
134+
135+
```
136+
108137
## Given Instance Initialization
109138

110139
A given instance without type or context parameters is initialized on-demand, the first

0 commit comments

Comments
 (0)