TL&DR: Is it possible to (locally?) disable path-dependent typing? I'd like to issue a single import statement similar to import x._
, but to make C
refer to X#C
rather than x.C
(X
being the type of x
)?
I have a bunch of types:
class Button[M] { ... }
class Label[M] { ... }
...
And I happen to use them together passing the same type argument to all of them:
class UseSite[M] (
btn1 : Button[M]
, btn2 : Button[M]
, lbl1 : Label[M]) {
...
}
I thought that it'd be nice to package all those types up so that I only need to pass the type parameter once:
class Swing[M] {
class Button { ... }
class Label { ...}
}
Then on the use site I'd like to be able to do this:
class WithSwing[M] {
val swing = new Swing[M]
import swing._
class UseSite(
btn1 : Button
, btn2 : Button
, lbl1 : Label) {
...
}
}
However, this does not work properly because of path-dependent typing: Button
refers to swing.Button
instead of Swing[M]#Button
so the external code has a very hard time passing the correct arguments to the UseSite
constructor.
Is there a nice way to make Button
refer to Swing[M]#Button
rather than to swing.Button
?
Assuming that the path dependencies really are accidental, then rather than chase type projections all the way through your codebase, you could try something like this,
class Button[M]
class Label[M]
trait Swing[M] {
type ButtonM = Button[M]
type LabelM = Label[M]
}
class WithSwing[M] {
val swing = new Swing[M] {}
import swing._
class UseSite(btn1 : ButtonM, btn2 : ButtonM, lbl1 : LabelM)
}
Outside WithSwing
usage would look like,
val ws = new WithSwing[String]
import ws.swing._
new ws.UseSite(new ButtonM {}, new ButtonM {}, new LabelM {})
Inheritance increases brevity somewhat,
class WithSwing[M] extends Swing[M] {
class UseSite(btn1 : ButtonM, btn2 : ButtonM, lbl1 : LabelM)
}
// Usage ...
val ws = new WithSwing[String]
import ws._
new ws.UseSite(new ButtonM {}, new ButtonM {}, new LabelM {})
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With