Functor application
Functors are factories that allow you to access particular specialization implementations of a callable. Q# currently supports two functors; the Adjoint
and the Controlled
, both of which can be applied to operations that provide the necessary specializations.
The Controlled
and Adjoint
functors commute; if ApplyUnitary
is an operation that supports both functors, then there is no difference between Controlled Adjoint ApplyUnitary
and Adjoint Controlled ApplyUnitary
.
Both have the same type and, upon invocation, execute the implementation defined for the controlled adjoint
specialization.
Adjoint functor
If the operation ApplyUnitary
defines a unitary transformation U of the quantum state, Adjoint ApplyUnitary
accesses the implementation of U†. The Adjoint
functor is its own inverse, since (U†)† = U by definition. For example, Adjoint Adjoint ApplyUnitary
is the same as ApplyUnitary
.
The expression Adjoint ApplyUnitary
is an operation of the same type as ApplyUnitary
; it has the same argument and return type and supports the same functors. Like any operation, it can be invoked with an argument of suitable type. The following expression applies the adjoint specialization of ApplyUnitary
to an argument arg
:
Adjoint ApplyUnitary(arg)
Controlled functor
For an operation ApplyUnitary
that defines a unitary transformation U of the quantum state, Controlled ApplyUnitary
accesses the implementation that applies U conditional on all qubits in an array of control qubits being in the |1⟩ state.
The expression Controlled ApplyUnitary
is an operation with the same return type and operation characteristics as ApplyUnitary
, meaning it supports the same functors.
It takes an argument of type (Qubit[], <TIn>)
, where <TIn>
should be replaced with the argument type of ApplyUnitary
, taking singleton tuple equivalence into account.
Operation | Argument Type | Controlled Argument Type |
---|---|---|
X | Qubit |
(Qubit[], Qubit) |
SWAP | (Qubit, Qubit) |
(Qubit[], (Qubit, Qubit)) |
Concretely, if cs
contains an array of qubits, q1
and q2
are two qubits, and the operation SWAP
is as defined here, then the following expression exchanges the state of q1
and q2
if all qubits in cs
are in the |1⟩ state:
Controlled SWAP(cs, (q1, q2))
Note
Conditionally applying an operation based on the control qubits being in a state other than the |1⟩ state may be achieved by applying the appropriate adjointable transformation to the control qubits before invocation, and applying the inverses after. Conditioning the transformation on all control qubits being in the |0⟩ state, for example, can be achieved by applying the X
operation before and after. This can be conveniently expressed using a conjugation. Nonetheless, the verbosity of such a construct may merit additional support for a more compact syntax in the future.