-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
26 additions
and
39 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -20,7 +20,7 @@ The following features are provided based on the compiler [strict equality](http | |
|
||
<br/> | ||
|
||
Please see the [FAQ](#faq) and [further considerations](#strict-equality-considerations) on strict equality for additional information. | ||
Please see the [FAQ](#faq) for additional information. | ||
|
||
|
||
# Quickstart | ||
|
@@ -107,7 +107,7 @@ Eq instances can be obtained in the following ways: | |
|
||
Verified equality for composed case classes via type class derivation: | ||
```scala | ||
case class Email( address:String) derives Eq | ||
case class Email(address: String) derives Eq | ||
|
||
// Only compiles because class Email derives Eq | ||
case class Person( | ||
|
@@ -123,7 +123,7 @@ person == person | |
|
||
Verified equality for composed case classes with type parameters via type class derivation: | ||
```scala | ||
case class Email( address:String) derives Eq | ||
case class Email(address: String) derives Eq | ||
|
||
// Only compiles because the type parameter A is declared with a context bound [A: Eq] | ||
case class Person[A: Eq]( | ||
|
@@ -134,16 +134,19 @@ case class Person[A: Eq]( | |
// Only compiles because class Email derives Eq | ||
val person = Person("Alice", Email("[email protected]")) | ||
|
||
// Only compiles because class Person derives Eq | ||
person == person | ||
``` | ||
|
||
Verified equality for an existing arbitrary class with a given using the same derivation mechanism: | ||
```scala | ||
// Only compiles because SomeProduct conforms to the equality rules | ||
given Eq[SomeProduct] = Eq.derived | ||
enum Weekday: | ||
case Monday, Tuesday, Wednesday // ... | ||
|
||
// Only compiles with the given instance above | ||
SomeProduct() == SomeProduct() | ||
given Eq[Weekday] = Eq.derived | ||
|
||
// Only compiles because given Eq type class instance for Weekday is in scope | ||
Weekday.Monday == Weekday.Monday | ||
``` | ||
|
||
|
||
|
@@ -229,7 +232,7 @@ import java.time.{LocalDate, LocalDateTime} | |
val now = LocalDateTime.now | ||
val later = LocalDateTime.now | ||
|
||
// Compiles out of the box | ||
// Only compiles because given Eq type class instance for LocalDateTime is in scope | ||
now == later | ||
|
||
val today = LocalDate.now | ||
|
@@ -413,37 +416,6 @@ import MyEq.{*, given} | |
``` | ||
|
||
|
||
# Strict equality considerations | ||
|
||
## Type Any | ||
|
||
Using `Any` as part of any type declaration with strict equality enabled will cause that type not to be comparable with `==` or `!=`. | ||
|
||
## Enums | ||
|
||
Enums are products and therefore equality can be obtained via `Eq` type class derivation. | ||
|
||
|
||
```scala | ||
enum Weekday derives Eq: | ||
// These are instances of the product type Weekday | ||
case Monday, Tuesday, Wednesday // ... | ||
|
||
// Only compiles because enum Weekday derives Eq | ||
val myDay: Weekday = Weekday.Monday | ||
myDay == myDay | ||
``` | ||
|
||
## Checking strict equality build settings | ||
|
||
To guarantee the build has `-language:strictEquality` enabled, include this in your sources: | ||
|
||
```scala | ||
// Does not need to be called, it fails to compile with strict equality turned off | ||
checkStrictEqualityBuild() | ||
``` | ||
|
||
|
||
# FAQ | ||
|
||
## What is the relation between `Eq` and `CanEqual`? | ||
|
@@ -484,6 +456,12 @@ This library focuses on strict equality and therefore the `Eq` type class can be | |
* For unrelated types `A` and `B`, `given Eq[A]` allows pairwise comparison between values of `A`, or `A & B`. | ||
|
||
|
||
## Can types parametrized with `Any` support equality ? | ||
|
||
No, they don't, because they would require for the type `Any` to support equality, which would defeat the purpose. | ||
|
||
|
||
|
||
## Why do `enum` types need to derive `Eq` to be equality-safe ? | ||
|
||
It does not seem to be possible to create given Eq instances for enum types automatically in Scala 3 without using a compiler plugin. | ||
|
@@ -504,6 +482,13 @@ case class Box[A: Eq](a: A) derives Eq, CanEqual | |
Box(1) == Box(2L) | ||
``` | ||
|
||
## How to verify that strict equality is enabled in build settings ? | ||
|
||
```scala | ||
// Call this function anywhere in your sources | ||
checkStrictEqualityBuild() | ||
``` | ||
|
||
## | ||
|
||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -75,6 +75,7 @@ def verified_equality_for_composed_case_classes_with_type_parameters_via_type_cl | |
// Only compiles because class Email derives Eq | ||
val person = Person("Alice", Email("[email protected]")) | ||
|
||
// Only compiles because class Person derives Eq | ||
person == person | ||
|
||
case class SomeProduct() | ||
|