úÎU)QA      !"#$%&'()*+,-./0123456789:;<=>?@ ABCWInspect the dynamic pointer tagging bits of a closure. This is an impure function that s relies on GHC internals and will falsely return 0, but (hopefully) never give the wrong tag number if it returns  a non-0 value. \Returns a guess as to whether or not a value has been evaluated. This is an impure function c that relies on GHC internals and will return false negatives, but (hopefully) no false positives.  g f a evaluates f g while forcing a, if g == a then f g is returned. Otherwise f a is evaluated. lFurthermore, if the argument has already been evaluated, we avoid sparking the parallel computation at all.  If a good guess at the value of aW is available, this is one way to induce parallelism in an otherwise sequential task. However, if the guess isn']t available more cheaply than the actual answer, then this saves no work and if the guess is 0 wrong, you risk evaluating the function twice.   spec a f a = f $! a #The best-case timeline looks like:   [---- f g ----]  [----- a -----]  [-- spec g f a --] $The worst-case timeline looks like:   [---- f g ----]  [----- a -----] " [---- f a ----] " [------- spec g f a -----------] !Compare these to the timeline of f $! a:  [---- a -----]  [---- f a ----] Unlike _, this version does not check to see if the argument has already been evaluated. This can save T a small amount of work when you know the argument will always require computation. ) with a user defined comparison function ) with a user defined comparison function + comparing by projection onto another type + comparing by projection onto another type  DE g f a evaluates f g while forcing a, if g == a then f g* is returned. Otherwise the side-effects 4 of the current STM transaction are rolled back and f a is evaluated. If the argument a is already evaluated, we don't bother to perform f g at all.  If a good guess at the value of aW is available, this is one way to induce parallelism in an otherwise sequential task. However, if the guess isn']t available more cheaply than the actual answer then this saves no work, and if the guess is 0 wrong, you risk evaluating the function twice.   specSTM a f a = f $! a #The best-case timeline looks like:   [------ f g ------]  [------- a -------]  [--- specSTM g f a ---] $The worst-case timeline looks like:   [------ f g ------]  [------- a -------] ( [-- rollback --] ? [------ f a ------] : [------------------ spec g f a ------------------------] !Compare these to the timeline of f $! a:  [------- a -------] ' [------ f a ------] Unlike ,  doesn'4t check if the argument has already been evaluated. * using a user defined comparison function * using a user defined comparison function   . F (==)'   . F (==)' GH   <IJKLM Given a valid estimate g,   g f xs yields the same answer as   f xs. g nP should supply an estimate of the value of the monoidal summation over the last n elements of the container. If g nd is accurate a reasonable percentage of the time and faster to compute than the fold, then this can 2 provide increased opportunities for parallelism.   using  Given a valid estimate g,  g f xs yields the same answer as  f xs. g nP should supply an estimate of the value of the monoidal summation over the last n elements of the container. If g nd is accurate a reasonable percentage of the time and faster to compute than the fold, then this can 2 provide increased opportunities for parallelism. Given a valid estimator g,  g f z xs yields the same answer as foldr' f z xs. g nL should supply an estimate of the value returned from folding over the last n elements of the container. If g nd is accurate a reasonable percentage of the time and faster to compute than the fold, then this can 2 provide increased opportunities for parallelism. Given a valid estimator g,  g f z xs yields the same answer as foldl' f z xs. g nM should supply an estimate of the value returned from folding over the first n elements of the container. If g nd is accurate a reasonable percentage of the time and faster to compute than the fold, then this can 2 provide increased opportunities for parallelism. EMap each element of a structure to an action, evaluate these actions , from left to right and ignore the results.  is  with its arguments flipped. PMap each element of the structure to a monadic action, evaluating these actions , from left to right and ignore the results.  is  with its arguments flipped. !"#$%&'()*+,-./0123456789:;<=>?@NOP4  !"#$%&'()*+,-./0123456789:;<=>?@4  !"#$%&'()*+,-.12/03456789:;<=>?@4  !"#$%&'()*+,-./0123456789:;<=>?@Q      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEEFGGHIJKLMNOPPQRSTspeculation-0.3.0Control.Concurrent.Speculation"Control.Concurrent.STM.SpeculationData.Foldable.Speculation evaluatedspecspec'specByspecBy'specOnspecOn'specSTMspecSTM' specBySTM specBySTM' specOnSTM specOnSTM'foldfoldByfoldMap foldMapByfoldrfoldrByfoldlfoldlByfoldr1foldr1Byfoldl1foldl1By traverse_ traverseBy_for_forBy_mapM_mapMBy_forM_forMBy_ sequenceA_ sequenceABy_ sequence_ sequenceBy_asumasumBymsummsumBytoListtoListByconcatconcatBy concatMap concatMapByandorallanysumsumByproduct productBymaximum maximumByminimum minimumByelemelemBynotElem notElemByfindfindByBoxtag Speculationbase Data.FunctiononspeculationSupplyfreshSpeculationMaybeAcc NothingAccJustAccAcc extractAcc fromMaybeAccerrorEmptyStructure