2013-09-08 2 views
0

나는 스칼라를 배울 길을 걷고 있으며, 반항, 공변량, 불변 등을 이해하는 데 어려움을 겪고 있습니다. Why doesn't the example compile, aka how does (co-, contra-, and in-) variance work?에서 나는 다른 함수의 하위 유형으로 간주되는 방법을 배웠습니다. (정말 유용합니다!)스칼라 익명 함수 genric variance issues

아래 코드는 내 퍼즐을 푸는 데 중요한 부분이라고 생각합니다. 불필요하게 복잡 해지는 부분을 추출했습니다. 예제에 따르면 함수를 생성하는 팩토리로 작동 할 Student 객체가 있습니다.

함수는 AnyVal (Int, Double, Long 등)의 유형 또는 하위 항목을 취하며 출력 결과는 동일한 입력 유형입니다. 이를 달성하기 위해 학생 클래스는 AnyVal의 부속 유형 인 제네릭 (A)을 사용합니다. List [Master [AnyVal]] (Student.func1)과 같은 것을함으로써 이러한 학생들의 목록을 참조 할 수 있도록 추상 클래스가 있습니다.

문제점은 "val function : List [A] =>"오류가 발생하면 "공변 유형 A가 유형이 반 contravariant 위치에서 발생한다는 것입니다.> List [A] => A 값 기능". 리턴 타입이 A.의 반 차별이어야하는 이유는 모르겠다. 나는 Function1 특성에 기반한 이름에 대해이 사실을 다소 받아 들일 수있다.

그렇다면 추상 마스터 클래스에서 함수를 정의하면 반환 유형이 유형 A의 반 변형이 될 수 있습니까? 함수 정의 (예 : def 함수 [B> : A] (v : B) : List [B])를 사용하여이를 정의하는 방법의 예제를 발견했지만 익명 함수로 어떻게 구현할 수 있습니까? 마스터 추상 클래스의 "A"는 모든 AnyVal 유형 (Int, Double 등)을 포함하는 함수 목록이 있기 때문에 공변해야 함을 기억하십시오.

정말 감사드립니다! 내 용어가 꺼져 있으면 알려줘. 스칼라 학습자

abstract class Master[+A] { 
    val function: List[A] => A 
} 

class Student[A <: AnyVal](val function: List[A] => A) extends Master[A] 

object Student { 
def func1 = 
    new Student((params: List[Int])=>params(0) + params(1)) 
} 

val myFunc = Student.func1 
val someList = List[Master[AnyVal]](myFunc) 
+0

어떻게하면 컴파일 할 수 있는지 모르겠다. 'Function'은 객체입니다. Scala와 JS를 혼합하고 있습니까? :) – pedrofurla

+1

"새로운 학생 (params : List [Int]) => params (0) + params (1))"그 점을 지적 해 주셔서 감사합니다. – Miles

답변

0

공진 유형으로 매개 변수화 된 제네릭 클래스 또는 특성을 만드는 것은 매우 어렵습니다. 일단 분산 주석을 추가하면 해당 클래스 메소드의 매개 변수로 해당 유형을 사용할 수 없습니다. 이는 함수가 매개 변수에서 반비례이고 반환 유형에서 공변수이기 때문입니다. this 대답에 대한 설명이 있습니다.

유형을 공변수로 만들려면 [B> : A] 유형의 매개 변수를 취하는 모든 메소드를 작성해야합니다. 즉, 매개 변수 유형으로 A의 수퍼 유형을 가져와야합니다. 이것은 상당히 어려울 수 있습니다. 온라인 스칼라 문서에는 필요한 곡예가 example 있습니다.