You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/_docs/reference/experimental/typeclasses.md
+35-30
Original file line number
Diff line number
Diff line change
@@ -444,6 +444,39 @@ This is less of a disruption than it might appear at first:
444
444
- Simplification of the language since a feature is dropped
445
445
- Eliminate non-obvious and misleading syntax.
446
446
447
+
448
+
### Bonus: Fixing Singleton
449
+
450
+
We know the current treatment of `Singleton` as a type bound is broken since
451
+
`x.type | y.type <: Singleton` holds by the subtyping rules for union types, even though `x.type | y.type` is clearly not a singleton.
452
+
453
+
A better approach is to treat `Singleton` as a type class that is interpreted specially by the compiler.
454
+
455
+
We can do this in a backwards-compatible way by defining `Singleton` like this:
456
+
457
+
```scala
458
+
traitSingleton:
459
+
typeSelf
460
+
```
461
+
462
+
Then, instead of using an unsound upper bound we can use a context bound:
463
+
464
+
```scala
465
+
deff[X:Singleton](x: X) = ...
466
+
```
467
+
468
+
The context bound is treated specially by the compiler so that no using clause is generated at runtime (this is straightforward, using the erased definitions mechanism).
469
+
470
+
### Bonus: Precise Typing
471
+
472
+
This approach also presents a solution to the problem how to express precise type variables. We can introduce another special type class `Precise` and use it like this:
473
+
474
+
```scala
475
+
deff[X:Precise](x: X) = ...
476
+
```
477
+
Like a `Singleton` bound, a `Precise` bound disables automatic widening of singleton types or union types in inferred instances of type variable `X`. But there is no requirement that the type argument _must_ be a singleton.
478
+
479
+
447
480
## Summary of Syntax Changes
448
481
449
482
Here is the complete context-free syntax for all proposed features.
@@ -692,38 +725,10 @@ Dimi Racordon tried to [port some core elements](https://github.com/kyouko-taiga
692
725
693
726
With the improvements proposed here, the library can now be expressed quite clearly and straightforwardly. See tests/pos/hylolib in this PR for details.
694
727
695
-
## Suggested Improvements unrelated to Type Classes
696
-
697
-
The following two improvements elsewhere would make sense alongside the suggested changes to type classes. But only the first (fixing singleton) forms a part of this proposal and is implemented.
698
-
699
-
### Fixing Singleton
700
-
701
-
We know the current treatment of `Singleton` as a type bound is broken since
702
-
`x.type | y.type <: Singleton` holds by the subtyping rules for union types, even though `x.type | y.type` is clearly not a singleton.
703
-
704
-
A better approach is to treat `Singleton` as a type class that is interpreted specially by the compiler.
728
+
## Suggested Improvement unrelated to Type Classes
705
729
706
-
We can do this in a backwards-compatible way by defining `Singleton` like this:
730
+
The following improvement would make sense alongside the suggested changes to type classes. But it does not form part of this proposal and is not yet implemented.
707
731
708
-
```scala
709
-
traitSingleton:
710
-
typeSelf
711
-
```
712
-
713
-
Then, instead of using an unsound upper bound we can use a context bound:
714
-
715
-
```scala
716
-
deff[X:Singleton](x: X) = ...
717
-
```
718
-
719
-
The context bound is treated specially by the compiler so that no using clause is generated at runtime (this is straightforward, using the erased definitions mechanism).
720
-
721
-
_Aside_: This can also lead to a solution how to express precise type variables. We can introduce another special type class `Precise` and use it like this:
722
-
723
-
```scala
724
-
deff[X:Precise](x: X) = ...
725
-
```
726
-
This would disable automatic widening of singleton types in inferred instances of type variable `X`.
-- [E007] Type Mismatch Error: tests/neg/singleton-ctx-bound.scala:7:5 -------------------------------------------------
2
+
7 | f1(someInt) // error
3
+
| ^^^^^^^
4
+
| Found: Int
5
+
| Required: Singleton
6
+
|
7
+
| longer explanation available when compiling with `-explain`
8
+
-- [E007] Type Mismatch Error: tests/neg/singleton-ctx-bound.scala:12:5 ------------------------------------------------
9
+
12 | f2(someInt) // error
10
+
| ^^^^^^^
11
+
| Found: Int
12
+
| Required: Singleton
13
+
|
14
+
| longer explanation available when compiling with `-explain`
15
+
-- [E172] Type Error: tests/neg/singleton-ctx-bound.scala:13:26 --------------------------------------------------------
16
+
13 | f2(if ??? then 1 else 2) // error
17
+
| ^
18
+
|No given instance of type (1 : Int) | (2 : Int) is Singleton was found for parameter x$2 of method f2 in object Test. Failed to synthesize an instance of type (1 : Int) | (2 : Int) is Singleton: (1 : Int) | (2 : Int) is not a singleton
19
+
-- [E007] Type Mismatch Error: tests/neg/singleton-ctx-bound.scala:17:5 ------------------------------------------------
20
+
17 | f3(someInt) // error
21
+
| ^^^^^^^
22
+
| Found: Int
23
+
| Required: Singleton
24
+
|
25
+
| longer explanation available when compiling with `-explain`
26
+
-- [E172] Type Error: tests/neg/singleton-ctx-bound.scala:18:26 --------------------------------------------------------
27
+
18 | f3(if ??? then 1 else 2) // error
28
+
| ^
29
+
|No given instance of type Singleton{type Self = (1 : Int) | (2 : Int)} was found for a context parameter of method f3 in object Test. Failed to synthesize an instance of type Singleton{type Self = (1 : Int) | (2 : Int)}: (1 : Int) | (2 : Int) is not a singleton
30
+
-- [E172] Type Error: tests/neg/singleton-ctx-bound.scala:33:6 ---------------------------------------------------------
31
+
33 |class D extends A: // error
32
+
|^
33
+
|No given instance of type Singleton{type Self = D.this.Elem} was found for inferring the implementation of the deferred given instance given_Singleton_Elem in trait A. Failed to synthesize an instance of type Singleton{type Self = D.this.Elem}: D.this.Elem is not a singleton
0 commit comments