爲什麼第一種方法無法編譯?
I've opened a bug for this issue。
這似乎是隱式搜索中的編譯器怪癖。由於您提供convert
方法轉換Seq[A] => Seq[B]
,編譯器無法正確對齊類型。這是Ytyper-debug
編制的輸出:
| [search #3] start `[U, T](seq: Seq[U])(implicit converter: U => T)Seq[T]` inferring type T, searching for adaptation to pt=A => T (silent: method example in Test) implicits disabled
| [search #3] considering aToB
| |-- { ((a: A) => Conversions.aToB(a)) } : pt=A => ? EXPRmode (silent: method example in Test) implicits disabled
| | |-- ((a: A) => Conversions.aToB(a)) : pt=A => ? EXPRmode (silent: method example in Test) implicits disabled
| | | |-- Conversions.aToB(a) EXPRmode (silent: value $anonfun in Test) implicits disabled
| | | | |-- Conversions.aToB BYVALmode-EXPRmode-FUNmode-POLYmode (silent: value $anonfun in Test) implicits disabled
| | | | | \-> (a: A)B
| | | | |-- a : pt=A BYVALmode-EXPRmode (silent: value $anonfun in Test) implicits disabled
| | | | | \-> A
| | | | \-> B
| | | \-> A => B
| | \-> A => B
| [adapt] aToB adapted to { ((a: A) => Conversions.aToB(a)) } based on pt A => T
| [search #3] solve tvars=?T, tvars.constr= >: B
| solving for (T: ?T)
| [search #3] success inferred value of type A => =?B is SearchResult({
| ((a: A) => Conversions.aToB(a))
| }, TreeTypeSubstituter(List(type T),List(B)))
| solving for (A: ?A)
| solving for (A: ?A)
| solving for (A: ?A)
| solving for (A: ?A)
| [search #3] considering $conforms
| solving for (A: ?A)
| [adapt] $conforms adapted to [A]=> <:<[A,A] based on pt A => T
| [search #3] solve tvars=?T, tvars.constr= >: A
| solving for (T: ?T)
| [search #3] success inferred value of type A => =?A is SearchResult(scala.Predef.$conforms[A], TreeTypeSubstituter(List(type T),List(A)))
這似乎是搜索#3是努力適應conforms
(<:<
),這需要從A => B
到A => A
整個隱含的搜索。如果我與-Yno-predef
編譯,隱式轉換成功:
| | |-- [U, T](seq: Seq[U])(implicit converter: U => T)Seq[T] : pt=Seq[B] EXPRmode (silent: method example in Test) implicits disabled
| | | [search #4] start `[U, T](seq: Seq[U])(implicit converter: U => T)Seq[T]`, searching for adaptation to pt=A => B (silent: method example in Test) implicits disabled
| | | [search #4] considering aToB
| | | |-- { ((a: A) => Conversions.aToB(a)) } : pt=A => B EXPRmode (silent: method example in Test) implicits disabled
| | | | |-- ((a: A) => Conversions.aToB(a)) : pt=A => B EXPRmode (silent: method example in Test) implicits disabled
| | | | | |-- Conversions.aToB(a) : pt=B EXPRmode (silent: value $anonfun in Test) implicits disabled
| | | | | | |-- Conversions.aToB BYVALmode-EXPRmode-FUNmode-POLYmode (silent: value $anonfun in Test) implicits disabled
| | | | | | | \-> (a: A)B
| | | | | | |-- a : pt=A BYVALmode-EXPRmode (silent: value $anonfun in Test) implicits disabled
| | | | | | | \-> A
| | | | | | \-> B
| | | | | \-> A => B
| | | | \-> A => B
| | | [adapt] aToB adapted to { ((a: A) => Conversions.aToB(a)) } based on pt A => B
| | | [search #4] success inferred value of type A => B is SearchResult({
| | | ((a: A) => Conversions.aToB(a))
| | | },)
| | | |-- [U, T](seq: Seq[U])(implicit converter: U => T)Seq[T] : pt=Seq[B] EXPRmode (silent: method example in Test) implicits disabled
| | | | \-> Seq[B]
| | | [adapt] [U, T](seq: Seq[U])(implicit converter: U => T)Seq[T] adapted to [U, T](seq: Seq[U])(implicit converter: U => T)Seq[T] based on pt Seq[B]
| | | \-> Seq[B]
| | [adapt] Seq[A] adapted to [U, T](seq: Seq[U])(implicit converter: U => T)Seq[T] based on pt Seq[B]
| | \-> Seq[B]
| \-> [def example]()Seq[B]
這是主題相關的類型擦除,如果是,如何 函子的使用與它幫助?
第二個例子的作品,因爲你現在鋪設明確如何使用Functor
型類Seq[A]
成Seq[B]
映射,因此當編譯器看到一個Seq[A]
,它有一個隱含的將其轉換爲Seq[B]
:
def example(): Seq[B] = Conversions.functorConvert[Seq, A, B](sa)({
((a: A) => Conversions.aToB(a))
}, Conversions.SeqFunctor);
注意你需要從雙方一A => B
轉換和Functor[Seq]
能夠全部A
點地圖交給他們轉換爲B
s,這是它不使用conversions.aToB
。
感謝您的回覆。完美的解釋。 –
@ andrii.ilin我的解釋實際上是有缺陷的,因爲我在第一個例子中錯過了轉換'Seq [A] => Seq [B]'的'convert'方法。現在挖掘它。 –
我以爲你的第一個解釋涵蓋了這一點。仍然感謝您的解釋。 –