2014-10-09 48 views

回答

1

如果推断出在一个参数列表中的类型,那么约束在随后PARAM名单的使用对。 (请参阅SO上的许多类似问题。)

但是,在参数列表中没有发生类似情况。

这不起作用或者:

scala> def g[V <: A](b: V => V#B) = b 
g: [V <: A](b: V => V#B)V => V#B 

scala> g((c: C) => "") 
<console>:11: error: type mismatch; 
found : String("") 
required: ?#B 

?意味着它没有固定的V,即使它只是解决了V

对比度:

scala> def k[V <: A](v: V)(f: V#B => V) = 42 
k: [V <: A](v: V)(f: V#B => V)Int 

scala> k(new C)(_ => new C) 
res5: Int = 42 

当前的选项来使用是-Ytyper-debug。有时候可以理解输出。

对于你的例子f(_ => new C),你可以看到它立即在x$1上失败,即使人们希望它回溯并纠正自己。

| | | | |-- ((x$1) => new C()) : pt=?#B => ? BYVALmode-EXPRmode-POLYmode (site: value res0 in $iw) 
<console>:11: error: missing parameter type 
       f(_ => new C) 
       ^
| | | | | |-- new C() EXPRmode (site: value $anonfun in $iw) 
| | | | | | |-- new C BYVALmode-EXPRmode-FUNmode-POLYmode (silent: value $anonfun in $iw) 
| | | | | | | |-- new C EXPRmode-POLYmode-QUALmode (silent: value $anonfun in $iw) 
| | | | | | | | |-- C FUNmode-TYPEmode (silent: value $anonfun in $iw) 
| | | | | | | | | \-> C 
| | | | | | | | \-> C 
| | | | | | | \->()C 
| | | | | | \-> C 
| | | | | \-> <error> => C 
| | | | solving for (V: ?V) 
| | | | \-> C#B => C 

还有

http://www.scala-lang.org/files/archive/spec/2.11/06-expressions.html#local-type-inference

0

我相信问题是,它是否含糊解释你的对象为C类型或A,因为两者都是上界由A。我想你可以争辩说编译器应该知道后者并不完全合理,因为BA内是抽象的。但我能得到这个工作,参照BA直接,而不是通过V

scala> trait A { type B } 
defined trait A 

scala> case class C() extends A { type B = String } 
defined class C 

scala> def f[V <: A](b: A#B => V) = b 
f: [V <: A](b: A#B => V)A#B => V 

scala> f(a => new C()) 
res0: A#B => C = <function1> 
+0

您解决移动问题:RES0( “42”)不起作用。 – 2014-10-10 08:15:19

+0

公平起见,你只问过为什么底线不能编译。 – acjay 2014-10-10 12:32:52

相关问题