úÎO]NbCopObserveWith f takes an equivalence relation f, splits the state F space into equivalence classes based on f, and then randomly chooses ? one based on the probablity sum of each class. The output is  the chosen class. Lclassify is a helper function for opObserveWith which splits the input into N equivalence classes, finding the sum of the amplitudes of the states in each M class (for selection purposes). It returns a state vector of (a, QStateVec O (a,b)): the first element of the tuple is an arbitrary representitave of the P class; the second element is the class itself (represented as a state vector). Kpick is a helper function for opObserveWith which takes a state vector and L chooses an element from it at random based on the argument squared of the  probability amplitudes. GopEntangle is an Operator arrow which takes a list of eigenstates and 8 amplitudes and constructs a state vector out of them. EopLift takes an action in the underlying monad and converts it into K a quantum arrow. The arrow observes the input to the action, collapsing * the state, before performing the action. CrunOperator takes an input state vector, runs it through the given 8 Operator arrow, and returns a state vector of outputs. 9observeBranch forces the computation to collapse into a  single branch:  - x <- entangle -< [(1, 1 :+ 0), (2, 1 :+ 0)]  if x == 1  then do ... ? observeBranch -- decide NOW whether x is 1 or not  else ... This is the* function for which the two-stage Operator/Quantum > distinction was written, to be able to collapse conditionals  after they happen rather than as they happen. :entangle takes as input a list of values and probability ? amplitudes and gives as output a superposition of the inputs.  For example: - x <- entangle -< [(1, 1 :+ 0), (2, 0 :+ 1)]  -- x is now |1> + i|2> = qLift print -< x -- prints 1 or 2 with equal probability  qLift f -< x first collapses x' to an eigenstate (using observe) then  executes f xB in the underlying monad. All conditionals up to this point are 1 collapsed to an eigenstate (True or False) so a current branch of  the computation is selected. qLift_ is just qIO which doesn't take an input. eg.  $ qLift_ $ print "hello world" -< () BAll conditionals up to this point are collapsed to an eigenstate  (True or False) so a current branch! of the computation is selected.  observeWith f3 takes an equivalence relation f, breaks the state B space into eigenstates of that relation, and collapses to one.  For example:  1 x <- entangle -< map (\s -> (s,1 :+ 0)) [1..20] . observeWith (\x y -> x `mod` 2 == y `mod` 2) Will collapse x- to be either even or odd, but make no finer  decisions than that. )observe is just observeWith on equality. BrunQuantum takes an input state vector, runs it through the given 7 Quantum arrow, and returns a state vector of outputs. execQuantum q x, passes the state |x> through q, collapses q's * output to an eigenstate, and returns it. EThe Quantum arrow represents a quantum computation with observation. C You can give a quantum computation a superposition of values, and D it will operate over them, returning you a superposition back. If D ever you observe (using the qLift or qLift_ functions), the system 2 collapses to an eigenstate of what you observed.  - x <- entangle -< [(1, 1 :+ 0), (2, 1 :+ 0)] @ -- x is in state |1> + |2>; i.e. 1 or 2 with equal probability  let y = x + 1  -- y is in state |2> + |3> I qLift print -< y -- will print either 2 or 3; let's say it printed 2 ) -- state collapses here, y in state |2> B qLift print -< x -- prints 1 (assuming 2 was printed earlier) >So the variables become entangled with each other in order to + maintain consistency of the computation. =The Operator arrow is half of a Quantum arrow: it represents  the parallel2 nature of quantum computations, but only handles  choice in a pure way; that is, if you have:   if x > 0 " then opLift print -< "Hello" $ else opLift print -< "Goodbye" :Then if x represents a superposition of both positive and  negative numbers, both Hello and Goodbye will be printed > (x taking on positive values in the then branch and negative ? values in the else branch). This is leveraged by the Quantum ) arrow to do proper branch collapsation. ?It is implemented as a function from quantum states to quantum N states (under some MonadRandom for selection). But the states are augmented  by a dummy parameter d+ to keep track of the relationship between D the input and the output. So if the value |1> generated the value  |foo8> in the output, then we know that when we collapse the @ input to 1, whatever the output of this computation was has to  be collapsed to foo& simultaneously. The dummy parameter  implements entanglement! >A quantum state: a sum of eigenstates (represented as a list) An eigenstate, qsAmp |qsValue> *Representation of a probability amplitude      quantum-arrow-0.0.2Control.Arrow.QuantumentangleqLiftqLift_ observeWithobserve runQuantum execQuantumQuantum opObserveWithclassifypick opEntangleopLift runOperator observeBranchOperator QStateVecQStateAmp