2014-07-20 1 views
0

이 질문은 this one에서 영감을 받았습니다. 아래 예제에서 암시 적 매개 변수와 함께 예상 식 형식을 사용하면 형식 유추 관리자가 함수의 형식 매개 변수가 암시 적 인수를 제한하지 않는다고 결정하게되는 이유는 무엇입니까? (즉, 만약 실제로 여기에 무슨.)암시 적 매개 변수가있는 예상 유형 및 다형 함수가 형식 유추를 혼동합니까?

case class ThingA(name: String) 
case class ThingB(name: String) 

class ThingClass[T] 

implicit val thingClassA = new ThingClass[ThingA] 
implicit val thingClassB = new ThingClass[ThingB] 

def find[T](): Option[T] = None 
def findWithContextBound[T: ThingClass](): Option[T] = None 

val typeApplicationFind = find[ThingA]() 
val typeApplicationFindWithContextBound = findWithContextBound[ThingA]() 
val expectedTypeFind: Option[ThingA] = find() 
val expectedTypeFindWithContextBound: Option[ThingA] = findWithContextBound() 

마지막 표현이 모호한 경우에도 예상되는 형태가 findWithContextBound에 대한 형식 매개 변수를 제한해야한다.

답변

3

형식 매개 변수가 유추되기 전에 암시 적 해결책이 발생합니다. 마지막 줄에서 컴파일러가 암시 적으로 ThingClass을 검색 할 때 형식 매개 변수는 아직 확인되지 않은 T이므로 thingClassAthingClassB이 모두 허용되므로 컴파일러가 모호한 암시 적 값 오류로 인해 실패합니다.

왜 이런 식으로 스칼라가 작동합니까? 그것은 형식 매개 변수를 허용하고 따라서 반환 형식은 사용 가능한 implicits에 의해 결정됩니다. BitSetInt 인스턴스를 저장할 수

import collection.immutable.BitSet 
val bitSet = BitSet(1, 2) 
// another BitSet: 
val newBitSet = bitSet.map(_ + 1) 
// BitSet can't hold String, so this is a SortedSet: 
val notABitSet = bitSet.map(_.toString) 

이 사용하는 이유 중 하나는 매핑 BitSet입니다. BitSet.map은 암시 적으로 CanBuildFrom을 취합니다. 이는 특정 결과 콜렉션이 시작 콜렉션에서 빌드 될 수 있는지와 맵 결과를 포함하는지 여부를 나타냅니다. 함수의 반환 형식이 Int 일 때 다른 BitSet에 매핑 할 수있는 CanBuildFrom이 있으며 반환 형식에 관계없이 SortedSet을 만드는보다 일반적인 암시 적 표현이 있습니다. 첫 번째는 우선적으로 선택되지만 컴파일러는 필요할 때 두 번째로 폴백합니다.

관련 문제