다음을 통해 공유


형식 매개 변수화

Q# 형식 매개 변수가 있는 작업 및 함수를 지원합니다. Q# 표준 라이브러리는 형식 매개 변수가 있는 호출 가능 항목을 많이 사용하여 기능 언어에서 익숙한 MappedFold 같은 함수를 포함하여 유용한 추상화의 호스트를 제공합니다.

형식 매개 변수화의 개념에 동기를 부여하려면 지정된 함수를 배열의 각 값에 적용하고 계산 값이 있는 새 배열을 반환하는 함수 Mapped예를 고려합니다. 입력 및 출력 배열의 항목 형식을 지정하지 않고도 이 기능을 완벽하게 설명할 수 있습니다. 정확한 형식은 함수 Mapped구현을 변경하지 않으므로 임의 항목 형식에 대해 이 구현을 정의할 수 있어야 합니다. 입력 및 출력 배열의 항목에 대한 구체적인 형식이 지정된 경우 해당 함수 구현을 반환하는 팩터리 또는 템플릿 정의하려고 합니다. 이 개념은 형식 매개 변수의 형태로 공식화됩니다.

연결

모든 작업 또는 함수 선언은 호출 가능한 입력 또는 출력의 형식 또는 형식의 일부 또는 둘 다로 사용할 수 있는 하나 이상의 형식 매개 변수를 지정할 수 있습니다. 예외는 진입점이며 구체적이어야 하며 형식 매개 변수화할 수 없습니다. 형식 매개 변수 이름은 틱(')으로 시작하고 입력 및 출력 형식에서 여러 번 나타날 수 있습니다. 호출 가능한 서명에서 동일한 형식 매개 변수에 해당하는 모든 인수는 동일한 형식이어야 합니다.

형식 매개 변수가 있는 호출 가능 변수를 연결해야 합니다. 즉, 모든 형식 매개 변수를 구체적인 형식으로 바꿀 수 있도록 인수로 할당하거나 전달하기 전에 필요한 형식 인수를 제공해야 합니다. 형식은 기본 제공 형식, struct 형식 중 하나이거나 현재 범위 내에서 구체적인 형식인 경우 구체적인 형식으로 간주됩니다. 다음 예제에서는 형식이 현재 범위 내에서 구체적이라는 것이 무엇을 의미하는지 보여 줍니다. 아래에서 자세히 설명합니다.

    function Mapped<'T1, 'T2> (
        mapper : 'T1 -> 'T2,
        array : 'T1[]
    ) : 'T2[] {

        mutable mapped = new 'T2[Length(array)];
        for (i in IndexRange(array)) {
            mapped w/= i <- mapper(array[i]);
        }
        return mapped;
    }

    function AllCControlled<'T3> (
        ops : ('T3 => Unit)[]
    ) : ((Bool,'T3) => Unit)[] {

        return Mapped(CControlled<'T3>, ops); 
    }

CControlled 함수는 Microsoft.Quantum.Canon 네임스페이스에 정의됩니다. 'TIn => Unit 형식의 연산 op 인수로 사용하고 원래 연산을 적용하는 (Bool, 'TIn) => Unit 형식의 새 연산을 반환합니다. 클래식 비트(Bool형식)가 true 설정된 경우 이를 고전적으로 제어되는 op버전이라고도 합니다.

Mapped 함수는 'T1 임의의 항목 형식의 배열을 인수로 사용하고, 지정된 mapper 함수를 각 항목에 적용하고, 매핑된 항목을 포함하는 'T2[] 형식의 새 배열을 반환합니다. Microsoft.Quantum.Array 네임스페이스에 정의됩니다. 예제의 목적을 위해 형식 매개 변수는 두 함수의 형식 매개 변수에 동일한 이름을 지정하여 토론을 더 혼동하지 않도록 번호가 매겨집니다. 이 작업은 필요하지 않습니다. 다른 호출 가능 항목에 대한 형식 매개 변수의 이름은 같을 수 있으며 선택한 이름은 해당 호출 가능의 정의 내에서만 표시되고 관련이 있습니다.

AllCControlled 함수는 작업 배열을 사용하고 이러한 작업의 고전적으로 제어되는 버전을 포함하는 새 배열을 반환합니다. Mapped 호출하면 해당 형식 매개 변수 'T1'T3 => Unit확인되고 해당 형식 매개 변수는 (Bool,'T3) => Unit'T2. 확인 형식 인수는 지정된 인수의 형식에 따라 컴파일러에서 유추됩니다. 호출 식의 인수에 의해 암시적으로 정의된 말합니다. 같은 줄의 CControlled 대해 수행되는 것처럼 형식 인수를 명시적으로 지정할 수도 있습니다. 형식 인수를 유추할 수 없는 경우 명시적 연결 CControlled<'T3> 필요합니다.

'T3 형식은 AllCControlled호출 알려져 있으므로 AllCControlled컨텍스트 내에서 구체적입니다. 즉, 형식 매개 변수화할 수 없는 프로그램의 진입점이 알려지자마자 특정 형식 확인에 적합한 구현을 생성할 수 있도록 AllCControlled각 호출에 대한 구체적인 형식 'T3 알려져 있습니다. 프로그램에 대한 진입점이 알려지면 컴파일 타임에 형식 매개 변수의 모든 사용을 제거할 수 있습니다. 이 프로세스를 단형화.

런타임에만 수행되는 것이 아니라 컴파일 시간에 실제로 수행할 수 있도록 하기 위해 몇 가지 제한 사항이 필요합니다.

제한 사항

다음 예제를 고려하세요.

    operation Foo<'TArg> (
        op : 'TArg => Unit,
        arg : 'TArg
    ) : Unit {

        let cbit = RandomInt(2) == 0;
        Foo(CControlled(op), (cbit, arg));        
    } 

Foo 호출하면 무한 루프가 발생한다는 점을 무시하고 그림의 용도로 사용됩니다. Foo 전달된 원래 작업 op 고전적으로 제어된 버전과 원래 인수 외에 임의의 클래식 비트를 포함하는 튜플을 사용하여 자신을 호출합니다.

재귀의 각 반복에 대해 다음 호출의 형식 매개 변수 'TArg(Bool, 'TArg)확인됩니다. 여기서 'TArg 현재 호출의 형식 매개 변수입니다. 구체적으로 Foo 연산 HQubit형식의 인수 arg 호출한다고 가정합니다. 그런 다음 Foo 형식 인수 (Bool, Qubit)사용하여 자신을 호출한 다음, (Bool, (Bool, Qubit))형식 인수를 사용하여 Foo 호출합니다. 분명히 이 경우 Foo 컴파일 타임에 모노모핑할 수 없습니다.

형식 매개 변수가 있는 호출 가능 개체만 포함하는 호출 그래프의 주기에는 추가 제한이 적용됩니다. 각 호출 가능은 주기를 트래버스한 후 동일한 형식 인수 집합으로 호출되어야 합니다.

메모

덜 제한적일 수 있으며 주기에서 호출 가능한 각 호출에 대해 다음 함수의 경우와 같이 원래 형식 인수 집합을 사용하여 호출되는 주기 수가 유한합니다.

   function Bar<'T1,'T2,'T3>(a1:'T1, a2:'T2, a3:'T3) : Unit{
       Bar<'T2,'T3,'T1>(a2, a3, a1);
   }

간단히 하기 위해 더 제한적인 요구 사항이 적용됩니다. 형식 매개 변수 없이 하나 이상의 구체적인 호출 가능을 포함하는 주기의 경우 이러한 호출 가능은 해당 주기 내의 형식 매개 변수화된 호출 가능 개체가 항상 고정된 형식 인수 집합을 사용하여 호출되도록 합니다.