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

Popular posts from this blog

Fail to load namespace Spring Security http://www.springframework.org/security/tags -

sql - MySQL query optimization using coalesce -

unity3d - Unity local avoidance in user created world -