What a great idea.
It looks like hygiene issues with default args prohibit singleton types.
$ scala
Welcome to Scala 2.12.1 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_111).
Type in expressions for evaluation. Or try :help.
scala> private val x = new Object ; def f(foo: x.type = x, i: Int) = i
<console>:11: error: private value x escapes its defining scope as part of type x.type
private val x = new Object ; def f(foo: x.type = x, i: Int) = i
^
scala> val x = new Object ; def f(foo: x.type = (x: x.type), i: Int) = i
x: Object = java.lang.Object@1e54cb33
f: (foo: x.type, i: Int)Int
scala> f(i = 42)
<console>:13: error: type mismatch;
found : Object
required: x.type
f(i = 42)
^
or no, this looks OK:
private[this] val x: Object = new java.lang.Object();
<stable> <accessor> def x: Object = $iw.this.x;
def f(foo: x.type = $iw.this.x, i: Int): Int = i;
<synthetic> def f$default$1: x.type = $iw.this.x
or is the problem the assignment to the default value?
but you can't do this:
scala> val x: x.type = new Object
<console>:36: error: recursive value x needs type
val x: x.type = new Object
^
I guess this works because you don't have to tell it that x
is x.type
:
scala> object x
defined object x
scala> def f(y: x.type = x, i: Int) = i
f: (y: x.type, i: Int)Int
scala> f(i = 42)
res2: Int = 42
That still allows explicitly providing x
, which could be obfuscated.
I'm too scared to investigate why this fails:
scala> object x$$ ; def f(y: x$$.type = x$$, i: Int) = i
defined object x$$
f: (y: .type, i: Int)Int
scala> f(i = 42)
res0: Int = 42
scala> f(x$$, 42) // or x$$$
<console>:13: error: not found: value x$$
f(x$$, 42)
^
But that suggests that even though the object is public, access to it is somehow crippled by name mangling.