복붙노트

[SCALA] 왜 기능은 [-A1, ..., + B]되지 매개 변수와 같은 슈퍼 타입을 허용 어떻습니까?

SCALA

왜 기능은 [-A1, ..., + B]되지 매개 변수와 같은 슈퍼 타입을 허용 어떻습니까?

나는 하나가 '약간 넓은 (슈퍼) 유형의 값 대신에 좁은 (하위) 유형의 값을 사용할 수있는 능력'으로 (적어도, 객체에 대한) 공분산을 정의 할 수 있다고 생각하고, 그 contravariance는 정반대입니다 이.

명백하게, 스칼라 함수는 함수의 인스턴스 [-A1은, ..., + B]는 contravariant 파라미터 형 A1 등와 공변 리턴 타입, B.이, 함수에 대한 하위 유형을위한 상기 정의 된 의미 편리하지 않아야하지만 나는 매개 변수와 같은 슈퍼 타입을 전달할 수 있습니다?

내가 잘못이야 어디에 알려 주시기 바랍니다.

해결법

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

    1.공분산 및 contravariance는 매개 변수없는 특성 클래스의 특성입니다. (그들은 매개 변수에 의존하는 특성이있다, 그러나 그들은 클래스에 대한 진술을 확인하십시오.)

    공분산 및 contravariance는 매개 변수없는 특성 클래스의 특성입니다. (그들은 매개 변수에 의존하는 특성이있다, 그러나 그들은 클래스에 대한 진술을 확인하십시오.)

    따라서, (A)의 상위 클래스를 취하는 함수는 원래의 서브 함수로 간주 될 수 있다는 기능 1 [-A, + B] 수단.

    의 연습이를 보자 :

    class A
    class B extends A
    val printB: B => Unit = { b => println("Blah blah") }
    val printA: A => Unit = { a => println("Blah blah blah") }
    

    이제 당신은 B를 인쇄하는 방법을 알고있는 기능을 필요로한다고 가정

    def needsB(f: B => Unit, b: B) = f(b)
    

    당신은 printB에 전달할 수 있습니다. 그것은 또한 조식을 인쇄하는 방법을 알고 있기 때문에 그러나 당신은 또한 printA에 전달할 수 (더!), 단지처럼 => 단위 B => 단위의 서브 클래스이다. 이것은 정확히 contravariance 수단이다. 그것은 당신이 옵션 printB에 [더블]을 통과하고 아무것도하지만, 컴파일 타임 오류를 얻을 수 있습니다 의미하지 않는다!

    (공분산 다른 경우이다 : M [B] :

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

    2.이 질문은 오래,하지만 명확한 설명이리스 코프 치환 원칙을 호출하는 생각 : 슈퍼 클래스의 모든 서브 클래스의 진정한해야한다에 대해 사실 다. 당신은 당신이 어쩌면 더 푸와 함께 수행 할 수있는 SubFoo 모든 것을 함께 할 수 있어야합니다.

    이 질문은 오래,하지만 명확한 설명이리스 코프 치환 원칙을 호출하는 생각 : 슈퍼 클래스의 모든 서브 클래스의 진정한해야한다에 대해 사실 다. 당신은 당신이 어쩌면 더 푸와 함께 수행 할 수있는 SubFoo 모든 것을 함께 할 수 있어야합니다.

    가정 우리는이 옥양목 <: 고양이 : <동물, 허스키 <: 개 <: 동물. 펑션에서 살펴 보자 [고양이, 개]. 어떤 문은 이것에 대해 해당? 두 가지가있다:

    (1) 당신은 어떤 고양이에 전달할 수 있습니다 (고양이의 서브 클래스 정도)

    (2) 당신은 반환 된 값에 어떤 개 메서드를 호출 할 수 있습니다

    기능 [고양이, 개] 메이크업 감각 : 그래서 기능 [옥양목, 개] <합니까? 아니, 슈퍼 클래스의 해당 문은 서브 클래스, 즉 문 (1)의 사실이 아니다. 당신은 옥양목 고양이를 취하는 기능에 어떤 고양이에 전달할 수 없습니다.

    기능 [고양이, 개] 메이크업 감각 :하지만 기능 [동물, 개] <합니까? 예, 슈퍼 클래스에 대한 모든 문은 서브 클래스의 사실이다. 나는 아직도 어떤 고양이에 전달할 수 있습니다 - 사실 나는 훨씬 더보다 할 수있다, 나는 어떤 동물에 전달할 수 있습니다 - 난 반환 값의 모든 개 메소드를 호출 할 수 있습니다.

    A는 <: 그래서, B가 의미하는 함수 [B를 _] <: 함수 [A, _]

    기능 [고양이, 개] 메이크업 감각 : 이제, 기능 [고양이, 허스키는] <합니까? 예, 슈퍼 클래스에 대한 모든 문은 서브 클래스의 해당; 난 여전히 고양이를 전달할 수 있고, 나는 아직도 반환 값의 모든 개 메서드를 호출 할 수 있습니다 - 사실 나는 훨씬 더보다 할 수있는, 내가 반환 값의 모든 허스키 메소드를 호출 할 수 있습니다.

    기능 [고양이, 개] 메이크업 감각 :하지만 기능 [고양이, 동물] <합니까? 아니, 슈퍼 클래스의 해당 문은 서브 클래스, 즉 문 (2)의 사실이 아니다. 나는 동물 만 사람이 사용할 수, 반환 된 값에 개 모든 방법을 사용할 수를 호출 할 수 없습니다.

    그래서 기능과 [동물, 허스키] 내가이 기능으로 할 수있는 모든 것을 할 수 있습니다 [고양이, 개] : 어떤 고양이에 전달할 수 있습니다, 나는 반환 된 값에 개 모든 메소드를 호출 할 수 있습니다. 그리고 더 많은 작업을 수행 할 수 있습니다 나는 다른 동물에 전달할 수 있습니다, 나는 개에 사용할 수없는 팍에서 사용할 수있는 방법으로 호출 할 수 있습니다. 함수 [동물 허스키] <: 함수 [고양이, 개]는 말이 그래서. 첫 번째 유형 파라미터는 수퍼, 서브 클래스가 상기 제 2로 대체 될 수있다.

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

    3.여기에 직장에서 두 개의 아이디어가있다. 하나는보다 구체적인 인수 함수 (라고 포섭)에 전달 될 수 있도록 하위 유형 사용하고 있습니다. 다른 하나는 기능 자체에 하위 유형을 확인하는 방법입니다.

    여기에 직장에서 두 개의 아이디어가있다. 하나는보다 구체적인 인수 함수 (라고 포섭)에 전달 될 수 있도록 하위 유형 사용하고 있습니다. 다른 하나는 기능 자체에 하위 유형을 확인하는 방법입니다.

    유형 검사 함수에 인수를 들어, 당신은 단지 주어진 인수가 선언 된 인수 유형의 하위 유형이 있는지 확인해야합니다. 결과는 선언 된 유형의 하위 유형이어야합니다. 당신이 실제로 하위 유형을 확인하는 곳이다.

    매개 변수 및의 콘트라 / 공동 분산은 주어진 기능 유형이 다른 함수 유형의 하위 유형인지 여부를 확인하고자 할 때의 유일한 요소를 초래한다. 타입 파라미터가 기능을 갖도록하는 경우 [A1, ..., B] 다음 인수 함수 입력 기능으로 갖는다 C1, ..., D] 여기서, A1 <: C1 ... 및 D <: B.

    이 논리는 스칼라 특정하지 않고 하위 유형과 다른 정적으로 입력 된 언어에 적용됩니다.

  4. ==============================

    4.좁은 (부)를 넓은 (초)로 변환 공변 수단. 예를 들어, 우리는 두 개의 클래스가 하나 동물 (슈퍼)이고, 다른 하나는, 우리가 고양이 동물을 변환 할 수 있습니다 다음 공변를 사용하는 고양이입니다.

    좁은 (부)를 넓은 (초)로 변환 공변 수단. 예를 들어, 우리는 두 개의 클래스가 하나 동물 (슈퍼)이고, 다른 하나는, 우리가 고양이 동물을 변환 할 수 있습니다 다음 공변를 사용하는 고양이입니다.

    콘트라 변종은 동물로 고양이를 의미 공변의 반대입니다.

    불가 수단은 변환 할 수 없습니다입니다.

  5. from https://stackoverflow.com/questions/10603982/why-is-function-a1-b-not-about-allowing-any-supertypes-as-parameters by cc-by-sa and MIT license