복붙노트

[SCALA] 형식 유추는 .toSet로 만든 설정에 실패?

SCALA

형식 유추는 .toSet로 만든 설정에 실패?

왜 형식 유추는 여기에 실패?

scala> val xs = List(1, 2, 3, 3)
xs: List[Int] = List(1, 2, 3, 3)

scala> xs.toSet map(_*2)
<console>:9: error: missing parameter type for expanded function ((x$1) => x$1.$times(2))
       xs.toSet map(_*2)

xs.toSet가 할당되어있는 경우 그러나, 그것은 컴파일합니다.

scala> xs.toSet
res42: scala.collection.immutable.Set[Int] = Set(1, 2, 3)

scala> res42 map (_*2)
res43: scala.collection.immutable.Set[Int] = Set(2, 4, 6)

또한,리스트에서 설정 변환, 다른 길을 가고, 그리고 목록에 매핑을 준수합니다.

scala> Set(5, 6, 7)
res44: scala.collection.immutable.Set[Int] = Set(5, 6, 7)

scala> res44.toList map(_*2)
res45: List[Int] = List(10, 12, 14)

해결법

  1. ==============================

    1.나는 호출이 체인 경우에도, "유일하게 가능한"유형을 추론하는 것이 좋을 것이다 동의하지만, 기술적 인 한계가있다.

    나는 호출이 체인 경우에도, "유일하게 가능한"유형을 추론하는 것이 좋을 것이다 동의하지만, 기술적 인 한계가있다.

    당신은 그 제약을 해결하여 다음 유형의 변수에, (하위 경계 필요한 암시 인수에서 발생) 제약을 수집, 표현을 통해 폭 우선 청소로 추론 생각할 수 있습니다. 이 방법은, 예를 들어, implicits는 형식 유추를 안내 할 수 있습니다. 당신의 예에서, 당신은 단지 xs.toSet의 표현식 보면 하나의 솔루션이있다하더라도, 나중에 체인 호출은 시스템이 시켰음 수 있도록 제약을 소개 할 수있다. 미해결 된 형태 변수를 떠나의 단점은 클로저 그 형식 유추가 알 수있는 대상 유형을 필요로하며, 따라서 실패 할 것입니다 (이것은에 가서 구체적인 무엇인가를 필요로 - 폐쇄의 필요한 유형과 인수 형식의 유형을해야합니다 둘은) 알 수없는 일.

    이제, 지연 제약을 풀 때 것은 추론, 우리는, 역 추적 모든 유형의 변수를 해결하고 다시 시도 할 수 실패 할 수 있지만, 이것은 구현하기 까다로운 (아마도 매우 비효율적)입니다.

  2. ==============================

    2.Q : 왜 내가 원하는 일을 할 toSet하지 않는 이유는 무엇입니까?

    Q : 왜 내가 원하는 일을 할 toSet하지 않는 이유는 무엇입니까?

    답변 : 그건 너무 쉬운 것입니다.

    Q :하지만 왜이 컴파일되지 않습니다? 목록 (1) .toSet.map (X => ...)

    A : 스칼라 컴파일러는 x는 int이며 추론 할 수 없습니다.

    Q : 뭐,이 바보인가?

    답변 : 음, 목록 [A] .toSet는 immutable.Set [A]를 반환하지 않습니다. 그것은> 알 수없는 B에 대한 immutable.Set [B]를 반환 A.를

    Q : 어떻게 알고했는데?

    답변 : Scaladoc에서.

    Q :하지만 toSet 그런 식으로 정의되는 이유는 무엇입니까?

    A : 당신은 가정 될 수 immutable.Set는 공변이지만 없습니다. 그것은 불변이다. 반환 형식이 불변으로 허용되지 않을 수 그리고 toSet의 반환 유형, 공변 위치에 있습니다.

    Q : 당신은, "공변 위치를"무슨 뜻 이죠?

    A는 : http://en.wikipedia.org/wiki/Covariance_and_contravariance_(computer_science) : 나에게 당신에 대한 위키 백과를 보자. 또한 Odersky, Venners & 스푼의 19 장을 참조하십시오.

    Q : 지금 이해합니다. 그런데 왜 불변 immutable.Set입니까?

    A : 왜 스칼라의 불변의 설정은 유형에 공변되지 않은 : 내가 당신을 위해 오버 플로우 스택하자?

    Q : 나는 항복. 어떻게 내 원래의 코드를 수정합니까?

    A :이 작동리스트 (1) .toSet [지능] .MAP (X => ...). 그래서이 수행합니다 목록 (1) .toSet.map ((X : INT) => ...)

    (프리드먼 & Felleisen에 사과와 함께. 들으 및 지원 ijuma을 paulp합니다)

    편집 : 가치있는 추가 정보가 아드리안의 대답에 모두가 여기에 코멘트에 토론에있다.

  3. ==============================

    3.타입 추론은 목록 # toSet의 서명이 그대로 제대로 작동하지 않습니다

    타입 추론은 목록 # toSet의 서명이 그대로 제대로 작동하지 않습니다

    def toSet[B >: A] => scala.collection.immutable.Set[B]
    

    컴파일러는 사용자의 통화에서 두 곳에서 유형을 추론해야합니다. 함수에서 매개 변수를 주석에 대한 대안은 명시 적 타입 인수를 toSet를 호출하는 것입니다 :

    xs.toSet[Int] map (_*2)
    

    최신 정보:

    컴파일러는 그냥 당신이 선 하나 하나를 입력 할 때 어떻게되는지 살펴 보자, 두 단계를 추론 할 수있는 이유 귀하의 질문에 대해서는 :

    scala> val xs = List(1,2,3)
    xs: List[Int] = List(1, 2, 3)
    
    scala> val ys = xs.toSet   
    ys: scala.collection.immutable.Set[Int] = Set(1, 2, 3)
    

    여기서 컴파일러이 경우 [지능]로 설정 YS 대한 가장 구체적인 타입을 추론한다. 이 유형은 현재 알려진, 그래서지도에 전달 된 함수의 유형을 유추 할 수있다.

    당신이 당신의 예에서 가능한 모든 타입의 매개 변수를 작성하는 경우 호출은 다음과 같이 기록 될 것입니다 :

    xs.toSet[Int].map[Int,Set[Int]](_*2)
    

    두 번째 유형 매개 변수 (자세한 내용은 스칼라 컬렉션을 구현하는 방법에 대해 살펴 위해) 돌려 주어진 콜렉션의 유형을 지정하는 데 사용된다. 이것은 내가 심지어 컴파일러가 추론하는 유형의 수를 과소 평가 의미한다.

    이 경우에는 지능을 추론하기 쉬운 것처럼 보일 수 있지만 (암시 적 변환, 싱글 타입처럼 스칼라의 다른 기능을 제공, 유지 mixin 등 특성)되지 않는 경우가 있습니다. 나는 그것을 할 수없는 말을하지 않습니다 - 그것은 스칼라 컴파일러가하지 않습니다 단지입니다.

  4. from https://stackoverflow.com/questions/5544536/type-inference-fails-on-set-made-with-toset by cc-by-sa and MIT license