2014-10-09 1 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. Я думаю, вы могли бы утверждать, что компилятор должен знать, что последнее не имеет полного смысла, поскольку B является абстрактным в пределах A. Но я был в состоянии получить эту работу, ссылаясь на B в A непосредственно, а не через 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") не работает. –

+0

Чтобы быть справедливым, вы только спрашивали, почему нижняя строка не компилируется. – acjay