@@ -28,6 +28,31 @@ import scala.quoted.*
2828opaque type Nullable [+ A ] = A | Null
2929
3030object Nullable extends NullableInstances {
31+ type Flattened [A ] = A match {
32+ case Nullable [x] => Nullable [x]
33+ case _ => Nullable [A ]
34+ }
35+
36+ private [data] sealed trait Flattening [A , B ] {
37+ def apply (value : Nullable [A ]): B
38+ }
39+
40+ private [data] object Flattening extends Flattening0 {
41+ given [A , B ](using next : Flattening [A , B ]): Flattening [Nullable [A ], B ] with {
42+ def apply (value : Nullable [Nullable [A ]]): B = {
43+ next(value.asInstanceOf [Nullable [A ]])
44+ }
45+ }
46+ }
47+
48+ private [data] trait Flattening0 {
49+ given [A ]: Flattening [A , Nullable [A ]] with {
50+ def apply (value : Nullable [A ]): Nullable [A ] = {
51+ value
52+ }
53+ }
54+ }
55+
3156 // If we enable explicit nulls, strict equality needs this `CanEqual` for `== null` checks.
3257 // We keep it `private[data]` (not `private`) because explicit nulls are not enabled right now,
3358 // and a `private given` would otherwise trigger an unused-private-member warning.
@@ -79,11 +104,9 @@ object Nullable extends NullableInstances {
79104 inline def iterator : Iterator [A ] = {
80105 fold(Iterator .empty)(Iterator .single(_))
81106 }
82- }
83107
84- extension [A ](inline nested : Nullable [Nullable [A ]]) {
85- inline def flatten : Nullable [A ] = {
86- nested
108+ inline def flatten [B ](using flattening : Flattening [A , B ]): B = {
109+ flattening(nullable)
87110 }
88111 }
89112
0 commit comments