Open tcNickolas opened 1 month ago
This is an interesting one... I think the type system is working against you here in a valid but obscure way. The behavior of partial application is to try and turn the call invocation expression into the body of a function that matches the type of the expression being called, minus partial parameters. In this case, the expression being called is [Rx, Ry, Rz][DrawRandomInt(0, 2)]
which correctly has type (Double, Qubit) => Unit is Adj + Ctl
. The partial expression for the call is (1., _)
which removes the Double
and leaves the resolved type as Qubit => Unit is Adj + Ctl
. So now the logic that creates the implied lambda does so with that type and the body of the expression, effectively creating:
operation PartialApplication(q : Qubit) : Unit is Adj + Ctl {
[Rx, Ry, Rz][DrawRandomInt(0, 2)](1., _)
}
And then this fails adjoint and controlled generation later because DrawRandomInt
is neither adjointable or controllable. I don't think there is a good way to fix this (short of incorporating it into #504, which is bigger than a bug fix). In the meantime, a workaround that could allow the operation to get chosen at random during each call would be using lambda syntax directly, which infers functors:
let op = q => [Rx, Ry, Rz][DrawRandomInt(0, 2)][1., q];
That will produce an op
that gets a new choice from Rx
, Ry
, or Rz
each time, but is not itself adjointable or controllable.
Describe the bug
I'm trying to pick a random gate from an array, and using
DrawRandomInt
as the index fails because it doesn't support controlled and thus adjoint cannot be generated.To Reproduce
op
andop1
are initialized in the same way (except the variableind
), but the second one yields an error.Expected behavior
Two initializations of
op
andop1
should behave the same, since they do the same thing.Screenshots
System information