scala - Contravariance and val -
how , why 'val' , 'case' affect type system? (especially variance)
welcome scala version 2.8.1.final (java hotspot(tm) 64-bit server vm, java 1.6.0_22). type in expressions have them evaluated. type :help more information. scala> class e[-a] defined class e scala> class f[-a](val f: e[a] => unit) <console>:6: error: contravariant type occurs in covariant position in type => (e[a]) => unit of value f class f[-a](val f: e[a] => unit) ^ scala> case class c[-a](f: e[a] => unit) <console>:6: error: contravariant type occurs in covariant position in type => (e[a]) => unit of value f case class c[-a](f: e[a] => unit) scala> class f[-a](f: e[a] => unit) defined class f
consider this:
trait equal[-a] { def eq(a1: a, a2: a): boolean } val e = new equal[option[int]] { def eq(a1: option[int], a2: option[int]) = a1 forall (x => a2 forall (x ==)) } // because equal contra-variant, equal[anyref] subtype of equal[string] // because t => r contra-variant in t, equal[anyref] => unit supertype // of equal[string] => unit // follow assignment valid val f: equal[anyref] => unit = (e1: equal[string]) => println(e1.eq("abc", "def")) // f(e) doesn't compile because of contra-variance // equal[option[int]] not subtype of equal[anyref] // let's tell scala know doing class f[-a](val f: equal[a @uncheckedvariance] => unit) // , let's prove not: // because f contra-variant, f[option[int]] subtype of f[anyref] val g: f[option[int]] = new f(f) // , since g.f equal[option[int]] => unit, can pass e it. g.f(e) // compiles, throws exception
if f
not visible outside f
, problem can't happen.
Comments
Post a Comment