forked from scala/scala3
-
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.
Change MT reduction to call normalized rather than simplified
Transcribing and paraphrasing from smarter's comment in scala#16408 (comment) : Type erasure assumes method signatures aren't simplified, since simplification logic is implementation-defined. For instance, some intersection types can be simplified down, but intersection types and their simplification can erase to different types - prefering classes over traits, for instance (for Java interop, as it matches Java's erasure). Also note, simplify doesn't simplify intersections and unions in Type mode. But Match Types will cache their reduction without considering the type mode as a cache input, thus the simplified reduction leaks even when called in Type mode. Perhaps we don't need to reach for simplified and can simplify normalise down the reduced case (allowing for recursive match types to reduce down). Also the desire is to have both reducing cases normalize, rather than just the first one.
- Loading branch information
Showing
4 changed files
with
107 additions
and
2 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
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 |
---|---|---|
@@ -0,0 +1,26 @@ | ||
object Helpers: | ||
type NodeFun[R] = Matchable // compiles without [R] parameter | ||
|
||
type URIFun[R] = R match | ||
case GetURI[u] => u & NodeFun[R] | ||
|
||
private type GetURI[U] = RDF { type URI = U } | ||
end Helpers | ||
|
||
trait RDF: | ||
type URI | ||
|
||
trait ROps[R <: RDF]: | ||
def auth(uri: Helpers.URIFun[R]): String | ||
|
||
object TraitRDF extends RDF: | ||
override type URI = TraitTypes.UriImpl | ||
|
||
val rops = new ROps[TraitRDF.type] { | ||
override def auth(uri: Helpers.URIFun[TraitRDF.type]): String = ??? | ||
} | ||
end TraitRDF | ||
|
||
object TraitTypes: | ||
trait UriImpl // doesn't compile | ||
// class UriImpl // compiles |
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 |
---|---|---|
@@ -0,0 +1,22 @@ | ||
object Helpers: | ||
type NodeFun[R] = Matchable // compiles without [R] parameter | ||
|
||
type URIFun[R] = R match | ||
case RDF[u] => u & NodeFun[R] | ||
end Helpers | ||
|
||
trait RDF[URIParam] | ||
|
||
trait ROps[R <: RDF[?]]: | ||
def auth(uri: Helpers.URIFun[R]): String | ||
|
||
object TraitRDF extends RDF[TraitTypes.UriImpl]: | ||
|
||
val rops = new ROps[TraitRDF.type] { | ||
override def auth(uri: Helpers.URIFun[TraitRDF.type]): String = ??? | ||
} | ||
end TraitRDF | ||
|
||
object TraitTypes: | ||
trait UriImpl // doesn't compile | ||
// class UriImpl // compiles |
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 |
---|---|---|
@@ -0,0 +1,57 @@ | ||
import scala.util.Try | ||
|
||
trait RDF: | ||
rdf => | ||
|
||
type R = rdf.type | ||
type Node <: Matchable | ||
type URI <: Node | ||
|
||
given rops: ROps[R] | ||
end RDF | ||
|
||
object RDF: | ||
type Node[R <: RDF] = R match | ||
case GetNode[n] => Matchable //n & rNode[R] | ||
|
||
type URI[R <: RDF] <: Node[R] = R match | ||
case GetURI[u] => u & Node[R] | ||
|
||
private type GetNode[N] = RDF { type Node = N } | ||
private type GetURI[U] = RDF { type URI = U } | ||
end RDF | ||
|
||
trait ROps[R <: RDF]: | ||
def mkUri(str: String): Try[RDF.URI[R]] | ||
def auth(uri: RDF.URI[R]): Try[String] | ||
|
||
object TraitTypes: | ||
trait Node: | ||
def value: String | ||
|
||
trait Uri extends Node | ||
|
||
def mkUri(u: String): Uri = | ||
new Uri { def value = u } | ||
|
||
object TraitRDF extends RDF: | ||
import TraitTypes as tz | ||
|
||
override opaque type Node <: Matchable = tz.Node | ||
override opaque type URI <: Node = tz.Uri | ||
|
||
given rops: ROps[R] with | ||
override def mkUri(str: String): Try[RDF.URI[R]] = Try(tz.mkUri(str)) | ||
override def auth(uri: RDF.URI[R]): Try[String] = | ||
Try(java.net.URI.create(uri.value).getAuthority()) | ||
|
||
end TraitRDF | ||
|
||
class Test[R <: RDF](using rops: ROps[R]): | ||
import rops.given | ||
lazy val uriT: Try[RDF.URI[R]] = rops.mkUri("https://bblfish.net/#i") | ||
lazy val x: String = "uri authority=" + uriT.map(u => rops.auth(u)) | ||
|
||
@main def run = | ||
val test = Test[TraitRDF.type] | ||
println(test.x) |