Share via


하위 유형 및 분산

Q#은 몇 가지 변환 메커니즘만 지원합니다. 암시적 변환은 이항 연산자를 적용하거나 조건식을 평가하거나 배열 리터럴을 생성할 때만 수행할 수 있습니다. 이러한 경우 공통 상위 형식이 결정되고 필요한 변환이 자동으로 수행됩니다. 이러한 암시적 변환 외에도 함수 호출을 통한 명시적 변환이 가능하며 필요한 경우가 많습니다.

현재 존재하는 유일한 하위 형식 지정 관계는 연산에 적용됩니다. 필요한 함자 세트 이상을 지원하는 연산을 대체할 수 있어야 함을 직관적으로 이해할 수 있습니다. 구체적으로, 두 개의 구체적인 유형 TInTOut에 대해 하위 유형 관계는 다음과 같습니다.

    (TIn => TOut) :>
    (TIn => TOut is Adj), (TIn => TOut is Ctl) :>
    (TIn => TOut is Adj + Ctl)

여기서 A :> BBA의 하위 유형임을 나타냅니다. 다르게 표현하면 BA보다 더 제한적이므로 A 유형의 값이 필요한 모든 곳에서 B 유형의 값을 사용할 수 있습니다. 호출 가능 항목이 A 형식의 인수(항목)에 의존하는 경우 if가 필요한 모든 기능을 제공하므로 B 형식의 인수를 안전하게 대체할 수 있습니다.

동일한 수의 항목을 포함하고 각 항목의 형식이 A에 있는 해당 항목 형식의 하위 형식인 경우 B 형식의 튜플이 A 튜플 형식의 하위 형식이라는 점에서 이러한 종류의 다형성이 튜플로 확장됩니다. 이를 깊이 하위 유형이라고 합니다. 현재 너비 하위 형식 지정은 지원되지 않습니다. 즉, 두 사용자 정의 형식 또는 사용자 정의 형식과 기본 제공 형식 간에는 하위 형식 관계가 없습니다. 명명된 항목과 익명 항목이 모두 포함된 튜플을 추출할 수 있는 unwrap 연산자가 있으면 이를 방지할 수 있습니다.

참고

호출 가능 항목과 관련하여 호출 가능 항목에서 A 형식의 인수를 처리하는 경우 B 형식의 인수도 처리할 수 있습니다. 호출 가능 항목이 다른 호출 가능 항목에 인수로 전달되면 형식 서명이 요구하는 모든 것을 처리할 수 있어야 합니다. 이는 호출 가능 항목에서 B 형식의 인수를 처리할 수 있어야 하는 경우 A 형식의 더 일반적인 인수를 처리할 수 있는 호출 가능 항목을 안전하게 전달할 수 있음을 의미합니다. 반대로, 전달된 호출 가능 항목에서 A 형식의 값을 반환하도록 요구하는 경우 B 형식의 값을 반환하겠다는 약속으로 충분할 수 있습니다. 이는 해당 값에서 필요한 모든 기능을 제공할 것이기 때문입니다.

연산 또는 함수 형식은 인수 형식이 반공변이고 반환 형식이 공변입니다. 따라서 A :> B은 모든 구체적인 형식 T1에 대해 의미합니다.

    (B → T1) :> (A → T1), and
    (T1 → A) :> (T1 → B) 

여기서 는 함수 또는 연산을 의미할 수 있으며 특성에 대한 주석은 생략합니다. A를 각각 (B → T2)(T2 → A)로 바꾸고 B를 각각 (A → T2)(T2 → B)로 바꾸면 모든 구체적인 T2 형식에 대해 다음과 같은 결론에 도달합니다.

    ((A → T2) → T1) :> ((B → T2) → T1), and
    ((T2 → B) → T1) :> ((T2 → A) → T1), and
    (T1 → (B → T2)) :> (T1 → (A → T2)), and
    (T1 → (T2 → A)) :> (T1 → (T2 → B)) 

귀납법에 따르면 모든 추가 간접 참조는 인수 형식의 분산을 반전시키고 반환 형식의 분산을 변경하지 않은 채로 둡니다.

참고

이는 또한 배열의 분산 동작이 무엇이어야 하는지를 분명히 합니다. 항목 액세스 연산자를 통해 항목을 검색하는 것은 (Int -> TItem) 형식의 함수를 호출하는 것과 같습니다. 여기서 TItem는 배열의 요소 형식입니다. 이 함수는 배열을 전달할 때 암시적으로 전달되기 때문에 배열은 항목 종류에서 공변이어야 합니다. 튜플에 대해서도 동일한 고려 사항이 적용됩니다. 튜플은 변경할 수 없으므로 각 항목 종류에 대한 공변입니다. 배열을 변경할 수 있는 경우 항목을 배열에 설정하여 TItem 형식의 인수를 사용할 수 있는 구문이 있다는 것은 배열도 반변이어야 함을 의미합니다. 따라서 항목 가져오기 및 설정을 지원하는 데이터 형식에 대한 유일한 옵션은 고정입니다. 즉, 하위 유형 관계가 전혀 없습니다. B[]BA의 하위 형식인 경우에도 A[]의 하위 형식이 아닙니다. Q#의 배열은 변경 불가능이지만 공변이 아니라 불변입니다. 예를 들어 (Qubit => Unit is Adj)[] 형식의 값은 (Qubit => Unit)[] 형식의 인수가 필요한 호출 가능 항목에 전달할 수 없음을 의미합니다. 배열을 고정으로 유지하면 배열이 런타임으로 처리되고 최적화되는 방식과 관련하여 더 많은 유연성을 허용하지만 향후 이를 수정할 수도 있습니다.