scala - Confusing resolution of a named argument -
a following code giving me error scala 2.11.7 confusing me:
class a(val a: string, val bval: option[string] = none) { val b: string = bval.getorelse("") def copy(a: string = a, b: option[string] = some(b)) = new a(a, b) }
the intellij ide not showing error, on compile error:
error:(4, 52) type mismatch; found : option[string] required: string def copy(a: string = a, b: option[string] = some(b)) = new a(a, b) ^
for comparison, compiles fine:
class a(val a: string, val bval: option[string] = none) { val b = bval def copy(a: string = a, b: option[string] = some(b.getorelse(""))) = new a(a, b) }
when replace some(b)
some(this.b)
, error goes away, still confusing me why error there in first place. looks compiler resolving b
in some
parameter of copy
, not b
member of a
. if case, how can second version compile without error?
this has got bug. scope of default expression includes previous param lists.
scala> def x = 1 x: int scala> def f(x: int = x) = 2 * x f: (x: int)int scala> f() res0: int = 2
and -xprint:typer
shows default correct:
class extends scala.anyref { <paramaccessor> private[this] val a: string = _; <stable> <accessor> <paramaccessor> def a: string = a.this.a; <paramaccessor> private[this] val bval: option[string] = _; <stable> <accessor> <paramaccessor> def bval: option[string] = a.this.bval; def <init>(a: string, bval: option[string] = scala.none): = { a.super.<init>(); () }; private[this] val b: string = a.this.bval.getorelse[string](""); <stable> <accessor> def b: string = a.this.b; def copy(a: string = a, b: option[string] = scala.some.apply[a](<b: error>)): = new $iw.this.a(a, b); <synthetic> def copy$default$1: string = a.this.a; <synthetic> def copy$default$2: option[string] = scala.some.apply[string](a.this.b) }; <synthetic> object extends anyref { def <init>(): a.type = { a.super.<init>(); () }; <synthetic> def <init>$default$2: option[string] = scala.none }
yup.
scala> def y = "hi" y: string scala> def g(x: string)(y: option[string] = some(x)) = y map (_ * 2) g: (x: string)(y: option[string])option[string] scala> g("bye")() res0: option[string] = some(byebye) scala> def g(x: string)(y: option[string] = some(y)) = y map (_ * 2) <console>:11: error: type mismatch; found : option[string] required: string def g(x: string)(y: option[string] = some(y)) = y map (_ * 2) ^
edit: fact default method correct doesn't mean much, since there puzzlers related fact default methods not hygienic. e.g., http://scalapuzzlers.com/#pzzlr-051
Comments
Post a Comment