-
Notifications
You must be signed in to change notification settings - Fork 31
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
newtype extending newtype when underlying values extend eachother? #66
Comments
Here's how it might be expanded: type NFoo = NFoo.Type
object NFoo {
type Repr = Foo
type Base = Any { type NFoo$newtype }
trait Tag extends Any
type Type <: Base with Tag
implicit final class Ops$newtype(val $this$: Type) extends AnyVal {
def internal: Foo = $this$.asInstanceOf[Foo]
}
}
type NBar = NBar.Type
object NBar {
type Repr = Bar
type Base = Any { type NBar$newtype }
trait Tag extends Any
type Type <: NFoo.Type with Base with Tag
implicit final class Ops$newtype(val $this$: Type) extends AnyVal {
def internal: Bar = $this$.asInstanceOf[Bar]
}
} My only worry is the |
I have verified that the implicit ops don't conflict with each other. Taking the code above and using it to do: def doTheThingFoo(nfoo: NFoo): Foo = nfoo.internal
def doTheThingBar(nbar: NBar): Bar = nbar.internal
lazy val myBar: Bar = ???
doTheThingFoo(myBar.asInstanceOf[NBar]) compiles just fine. I don't yet have an easy way to test if it works at runtime, but I don't see why it wouldn't. |
I see what you mean. However, I'm a bit hesitant to make the encoding even more complex. However, you can get these same semantics with the following - import io.estatico.newtype.macros.newtype
object Main {
class Foo
class Bar extends Foo
@newtype case class N[+A](internal: T forSome { type T <: A })
type NFoo = N[Foo]
val NFoo: Foo => NFoo = N.apply
type NBar = N[Bar]
val NBar: Bar => NBar = N.apply
def printNFoo(nfoo: NFoo): Unit = println(nfoo)
def printNBar(nbar: NBar): Unit = println(nbar)
def main(args: Array[String]): Unit = {
val foo: Foo = new Foo
val bar: Bar = new Bar
val nfoo: NFoo = NFoo(foo)
val nbar: NBar = NBar(bar)
// Of course this works
printNFoo(nfoo)
// Works because NBar is a subtype of NFoo
printNFoo(nbar)
// Does not compile because NFoo is not a subtype of NBar
// printNBar(nfoo)
// Of course this works
printNBar(nbar)
}
} |
Can I make |
I think so; try adding the @newtype case class N[+A <: Foo](internal: T forSome { type T <: A }) |
Given:
why wouldn't
be valid?
The text was updated successfully, but these errors were encountered: