{-# LANGUAGE OverloadedStrings #-}
{-# OPTIONS_GHC -Wno-x-partial #-}

-- | Abstract types of performance measurement.
module Perf.Types
  ( -- * Measure
    Measure (..),
    repeated,
    StepMeasure (..),
    toMeasure,
    toMeasureN,
    step,
    stepM,
    multi,
    multiM,
    multiN,

    -- * function application
    fap,
    afap,
    ffap,
    fan,
    fam,
    (|$|),
    ($|),
    (|+|),

    -- * PerfT monad
    PerfT (..),
    Perf,
    runPerfT,
    evalPerfT,
    execPerfT,
    outer,
    slop,
    slops,
  )
where

import Control.DeepSeq
import Control.Monad
import Control.Monad.State.Lazy
import Data.Bifunctor
import Data.Functor.Identity
import Data.Map.Strict qualified as Map
import Data.Text (Text)
import GHC.Exts
import GHC.IO hiding (liftIO)
import Prelude

-- | Abstraction of a performance measurement within a monadic context.
--
-- - measure applies a function to a value, returning a tuple of the performance measure, and the computation result.
-- - measureM evaluates a monadic value and returns a performance-result tuple.
newtype Measure m t = Measure
  { forall (m :: * -> *) t.
Measure m t -> forall a b. (a -> b) -> a -> m (t, b)
measure :: forall a b. (a -> b) -> a -> m (t, b)
  }

instance (Functor m) => Functor (Measure m) where
  fmap :: forall a b. (a -> b) -> Measure m a -> Measure m b
fmap a -> b
f (Measure forall a b. (a -> b) -> a -> m (a, b)
m) =
    (forall a b. (a -> b) -> a -> m (b, b)) -> Measure m b
forall (m :: * -> *) t.
(forall a b. (a -> b) -> a -> m (t, b)) -> Measure m t
Measure
      (\a -> b
f' a
a' -> ((a, b) -> (b, b)) -> m (a, b) -> m (b, b)
forall a b. (a -> b) -> m a -> m b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((a -> b) -> (a, b) -> (b, b)
forall a b c. (a -> b) -> (a, c) -> (b, c)
forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first a -> b
f) ((a -> b) -> a -> m (a, b)
forall a b. (a -> b) -> a -> m (a, b)
m a -> b
f' a
a'))

-- | An inefficient application that runs the inner action twice.
instance (Applicative m) => Applicative (Measure m) where
  pure :: forall a. a -> Measure m a
pure a
t = (forall a b. (a -> b) -> a -> m (a, b)) -> Measure m a
forall (m :: * -> *) t.
(forall a b. (a -> b) -> a -> m (t, b)) -> Measure m t
Measure (\a -> b
f a
a -> (a, b) -> m (a, b)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (a
t, a -> b
f a
a))
  (Measure forall a b. (a -> b) -> a -> m (a -> b, b)
mf) <*> :: forall a b. Measure m (a -> b) -> Measure m a -> Measure m b
<*> (Measure forall a b. (a -> b) -> a -> m (a, b)
mt) =
    (forall a b. (a -> b) -> a -> m (b, b)) -> Measure m b
forall (m :: * -> *) t.
(forall a b. (a -> b) -> a -> m (t, b)) -> Measure m t
Measure
      (\a -> b
f a
a -> (\(a -> b
nf', b
fa') (a
t', b
_) -> (a -> b
nf' a
t', b
fa')) ((a -> b, b) -> (a, b) -> (b, b))
-> m (a -> b, b) -> m ((a, b) -> (b, b))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (a -> b) -> a -> m (a -> b, b)
forall a b. (a -> b) -> a -> m (a -> b, b)
mf a -> b
f a
a m ((a, b) -> (b, b)) -> m (a, b) -> m (b, b)
forall a b. m (a -> b) -> m a -> m b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (a -> b) -> a -> m (a, b)
forall a b. (a -> b) -> a -> m (a, b)
mt a -> b
f a
a)

-- | Convert a Measure into a multi measure.
repeated :: (Applicative m) => Int -> Measure m t -> Measure m [t]
repeated :: forall (m :: * -> *) t.
Applicative m =>
Int -> Measure m t -> Measure m [t]
repeated Int
n (Measure forall a b. (a -> b) -> a -> m (t, b)
p) =
  (forall a b. (a -> b) -> a -> m ([t], b)) -> Measure m [t]
forall (m :: * -> *) t.
(forall a b. (a -> b) -> a -> m (t, b)) -> Measure m t
Measure
    (\a -> b
f a
a -> ([(t, b)] -> ([t], b)) -> m [(t, b)] -> m ([t], b)
forall a b. (a -> b) -> m a -> m b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\[(t, b)]
xs -> (((t, b) -> t) -> [(t, b)] -> [t]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (t, b) -> t
forall a b. (a, b) -> a
fst [(t, b)]
xs, (t, b) -> b
forall a b. (a, b) -> b
snd ([(t, b)] -> (t, b)
forall a. HasCallStack => [a] -> a
head [(t, b)]
xs))) (Int -> m (t, b) -> m [(t, b)]
forall (m :: * -> *) a. Applicative m => Int -> m a -> m [a]
replicateM Int
n ((a -> b) -> a -> m (t, b)
forall a b. (a -> b) -> a -> m (t, b)
p a -> b
f a
a)))
{-# INLINEABLE repeated #-}

-- | Abstraction of a performance measurement with a pre and a post step wrapping the computation.
data StepMeasure m t = forall i. StepMeasure {()
pre :: m i, ()
post :: i -> m t}

instance (Functor m) => Functor (StepMeasure m) where
  fmap :: forall a b. (a -> b) -> StepMeasure m a -> StepMeasure m b
fmap a -> b
f (StepMeasure m i
start i -> m a
stop) = m i -> (i -> m b) -> StepMeasure m b
forall (m :: * -> *) t i. m i -> (i -> m t) -> StepMeasure m t
StepMeasure m i
start ((a -> b) -> m a -> m b
forall a b. (a -> b) -> m a -> m b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> b
f (m a -> m b) -> (i -> m a) -> i -> m b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. i -> m a
stop)

instance (Applicative m) => Applicative (StepMeasure m) where
  pure :: forall a. a -> StepMeasure m a
pure a
t = m () -> (() -> m a) -> StepMeasure m a
forall (m :: * -> *) t i. m i -> (i -> m t) -> StepMeasure m t
StepMeasure (() -> m ()
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()) (m a -> () -> m a
forall a b. a -> b -> a
const (a -> m a
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure a
t))
  <*> :: forall a b.
StepMeasure m (a -> b) -> StepMeasure m a -> StepMeasure m b
(<*>) (StepMeasure m i
fstart i -> m (a -> b)
fstop) (StepMeasure m i
start i -> m a
stop) =
    m (i, i) -> ((i, i) -> m b) -> StepMeasure m b
forall (m :: * -> *) t i. m i -> (i -> m t) -> StepMeasure m t
StepMeasure ((,) (i -> i -> (i, i)) -> m i -> m (i -> (i, i))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m i
fstart m (i -> (i, i)) -> m i -> m (i, i)
forall a b. m (a -> b) -> m a -> m b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> m i
start) (\(i
fi, i
i) -> i -> m (a -> b)
fstop i
fi m (a -> b) -> m a -> m b
forall a b. m (a -> b) -> m a -> m b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> i -> m a
stop i
i)

-- | Convert a StepMeasure into a Measure
toMeasure :: (Monad m) => StepMeasure m t -> Measure m t
toMeasure :: forall (m :: * -> *) t. Monad m => StepMeasure m t -> Measure m t
toMeasure (StepMeasure m i
pre' i -> m t
post') = (forall a b. (a -> b) -> a -> m (t, b)) -> Measure m t
forall (m :: * -> *) t.
(forall a b. (a -> b) -> a -> m (t, b)) -> Measure m t
Measure (m i -> (i -> m t) -> (a -> b) -> a -> m (t, b)
forall (m :: * -> *) i t a b.
Monad m =>
m i -> (i -> m t) -> (a -> b) -> a -> m (t, b)
step m i
pre' i -> m t
post')
{-# INLINEABLE toMeasure #-}

-- | Convert a StepMeasure into a Measure running the computation multiple times.
toMeasureN :: (Monad m) => Int -> StepMeasure m t -> Measure m [t]
toMeasureN :: forall (m :: * -> *) t.
Monad m =>
Int -> StepMeasure m t -> Measure m [t]
toMeasureN Int
n (StepMeasure m i
pre' i -> m t
post') = (forall a b. (a -> b) -> a -> m ([t], b)) -> Measure m [t]
forall (m :: * -> *) t.
(forall a b. (a -> b) -> a -> m (t, b)) -> Measure m t
Measure (((a -> b) -> a -> m (t, b)) -> Int -> (a -> b) -> a -> m ([t], b)
forall (m :: * -> *) a b t.
Monad m =>
((a -> b) -> a -> m (t, b)) -> Int -> (a -> b) -> a -> m ([t], b)
multi (m i -> (i -> m t) -> (a -> b) -> a -> m (t, b)
forall (m :: * -> *) i t a b.
Monad m =>
m i -> (i -> m t) -> (a -> b) -> a -> m (t, b)
step m i
pre' i -> m t
post') Int
n)
{-# INLINEABLE toMeasureN #-}

-- | A single step measurement.
step :: (Monad m) => m i -> (i -> m t) -> (a -> b) -> a -> m (t, b)
step :: forall (m :: * -> *) i t a b.
Monad m =>
m i -> (i -> m t) -> (a -> b) -> a -> m (t, b)
step m i
pre' i -> m t
post' !a -> b
f !a
a = do
  !i
p <- m i
pre'
  !b
b <- b -> m b
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (b -> m b) -> b -> m b
forall a b. (a -> b) -> a -> b
$! a -> b
f a
a
  !t
t <- i -> m t
post' i
p
  (t, b) -> m (t, b)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (t
t, b
b)
{-# INLINEABLE step #-}

-- | A single step measurement.
stepM :: (Monad m) => m i -> (i -> m t) -> m a -> m (t, a)
stepM :: forall (m :: * -> *) i t a.
Monad m =>
m i -> (i -> m t) -> m a -> m (t, a)
stepM m i
pre' i -> m t
post' m a
a = do
  !i
p <- m i
pre'
  !a
ma <- m a
a
  !t
t <- i -> m t
post' i
p
  (t, a) -> m (t, a)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (t
t, a
ma)
{-# INLINEABLE stepM #-}

multi1 :: (Monad m) => ((a -> b) -> a -> m (t, b)) -> Int -> (a -> b) -> a -> m [(t, b)]
multi1 :: forall (m :: * -> *) a b t.
Monad m =>
((a -> b) -> a -> m (t, b)) -> Int -> (a -> b) -> a -> m [(t, b)]
multi1 (a -> b) -> a -> m (t, b)
action Int
n !a -> b
f !a
a = [m (t, b)] -> m [(t, b)]
forall (t :: * -> *) (m :: * -> *) a.
(Traversable t, Monad m) =>
t (m a) -> m (t a)
forall (m :: * -> *) a. Monad m => [m a] -> m [a]
sequence ([m (t, b)] -> m [(t, b)]) -> [m (t, b)] -> m [(t, b)]
forall a b. (a -> b) -> a -> b
$ Int -> m (t, b) -> [m (t, b)]
forall a. Int -> a -> [a]
replicate Int
n (m (t, b) -> [m (t, b)]) -> m (t, b) -> [m (t, b)]
forall a b. (a -> b) -> a -> b
$! (a -> b) -> a -> m (t, b)
action a -> b
f a
a
{-# INLINEABLE multi1 #-}

-- | Return one result but multiple measurements.
multi :: (Monad m) => ((a -> b) -> a -> m (t, b)) -> Int -> (a -> b) -> a -> m ([t], b)
multi :: forall (m :: * -> *) a b t.
Monad m =>
((a -> b) -> a -> m (t, b)) -> Int -> (a -> b) -> a -> m ([t], b)
multi (a -> b) -> a -> m (t, b)
action Int
n !a -> b
f !a
a = do
  [(t, b)]
xs <- ((a -> b) -> a -> m (t, b)) -> Int -> (a -> b) -> a -> m [(t, b)]
forall (m :: * -> *) a b t.
Monad m =>
((a -> b) -> a -> m (t, b)) -> Int -> (a -> b) -> a -> m [(t, b)]
multi1 (a -> b) -> a -> m (t, b)
action Int
n a -> b
f a
a
  ([t], b) -> m ([t], b)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (((t, b) -> t) -> [(t, b)] -> [t]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (t, b) -> t
forall a b. (a, b) -> a
fst [(t, b)]
xs, (t, b) -> b
forall a b. (a, b) -> b
snd ([(t, b)] -> (t, b)
forall a. HasCallStack => [a] -> a
head [(t, b)]
xs))
{-# INLINEABLE multi #-}

-- | Multiple measurements
multiM :: (Monad m) => (m a -> m (t, a)) -> Int -> m a -> m ([t], a)
multiM :: forall (m :: * -> *) a t.
Monad m =>
(m a -> m (t, a)) -> Int -> m a -> m ([t], a)
multiM m a -> m (t, a)
action Int
n m a
a =
  ([(t, a)] -> ([t], a)) -> m [(t, a)] -> m ([t], a)
forall a b. (a -> b) -> m a -> m b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\[(t, a)]
xs -> (((t, a) -> t) -> [(t, a)] -> [t]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (t, a) -> t
forall a b. (a, b) -> a
fst [(t, a)]
xs, [a] -> a
forall a. HasCallStack => [a] -> a
head ([a] -> a) -> [a] -> a
forall a b. (a -> b) -> a -> b
$! ((t, a) -> a) -> [(t, a)] -> [a]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (t, a) -> a
forall a b. (a, b) -> b
snd [(t, a)]
xs)) (Int -> m (t, a) -> m [(t, a)]
forall (m :: * -> *) a. Applicative m => Int -> m a -> m [a]
replicateM Int
n (m a -> m (t, a)
action m a
a))
{-# INLINEABLE multiM #-}

multiN :: (b -> t) -> (a -> b) -> a -> Int -> IO t
multiN :: forall b t a. (b -> t) -> (a -> b) -> a -> Int -> IO t
multiN b -> t
frc = SPEC -> (a -> b) -> a -> Int -> IO t
forall {t} {t}. (Eq t, Num t) => SPEC -> (t -> b) -> t -> t -> IO t
multiNLoop SPEC
SPEC
  where
    multiNLoop :: SPEC -> (t -> b) -> t -> t -> IO t
multiNLoop !SPEC
_ t -> b
f t
x t
n
      | t
n t -> t -> Bool
forall a. Eq a => a -> a -> Bool
== t
1 = t -> IO t
forall a. a -> IO a
evaluate (b -> t
frc (t -> b
f t
x))
      | Bool
otherwise = do
          t
_ <- t -> IO t
forall a. a -> IO a
evaluate (b -> t
frc (t -> b
f t
x))
          SPEC -> (t -> b) -> t -> t -> IO t
multiNLoop SPEC
SPEC t -> b
f t
x (t
n t -> t -> t
forall a. Num a => a -> a -> a
- t
1)
{-# INLINE multiN #-}

-- | Performance measurement transformer storing a 'Measure' and a map of named results.
newtype PerfT m t a = PerfT
  { forall (m :: * -> *) t a.
PerfT m t a -> StateT (Measure m t, Map Text t) m a
measurePerf :: StateT (Measure m t, Map.Map Text t) m a
  }
  deriving ((forall a b. (a -> b) -> PerfT m t a -> PerfT m t b)
-> (forall a b. a -> PerfT m t b -> PerfT m t a)
-> Functor (PerfT m t)
forall a b. a -> PerfT m t b -> PerfT m t a
forall a b. (a -> b) -> PerfT m t a -> PerfT m t b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
forall (m :: * -> *) t a b.
Functor m =>
a -> PerfT m t b -> PerfT m t a
forall (m :: * -> *) t a b.
Functor m =>
(a -> b) -> PerfT m t a -> PerfT m t b
$cfmap :: forall (m :: * -> *) t a b.
Functor m =>
(a -> b) -> PerfT m t a -> PerfT m t b
fmap :: forall a b. (a -> b) -> PerfT m t a -> PerfT m t b
$c<$ :: forall (m :: * -> *) t a b.
Functor m =>
a -> PerfT m t b -> PerfT m t a
<$ :: forall a b. a -> PerfT m t b -> PerfT m t a
Functor, Functor (PerfT m t)
Functor (PerfT m t) =>
(forall a. a -> PerfT m t a)
-> (forall a b. PerfT m t (a -> b) -> PerfT m t a -> PerfT m t b)
-> (forall a b c.
    (a -> b -> c) -> PerfT m t a -> PerfT m t b -> PerfT m t c)
-> (forall a b. PerfT m t a -> PerfT m t b -> PerfT m t b)
-> (forall a b. PerfT m t a -> PerfT m t b -> PerfT m t a)
-> Applicative (PerfT m t)
forall a. a -> PerfT m t a
forall a b. PerfT m t a -> PerfT m t b -> PerfT m t a
forall a b. PerfT m t a -> PerfT m t b -> PerfT m t b
forall a b. PerfT m t (a -> b) -> PerfT m t a -> PerfT m t b
forall a b c.
(a -> b -> c) -> PerfT m t a -> PerfT m t b -> PerfT m t c
forall (f :: * -> *).
Functor f =>
(forall a. a -> f a)
-> (forall a b. f (a -> b) -> f a -> f b)
-> (forall a b c. (a -> b -> c) -> f a -> f b -> f c)
-> (forall a b. f a -> f b -> f b)
-> (forall a b. f a -> f b -> f a)
-> Applicative f
forall (m :: * -> *) t. Monad m => Functor (PerfT m t)
forall (m :: * -> *) t a. Monad m => a -> PerfT m t a
forall (m :: * -> *) t a b.
Monad m =>
PerfT m t a -> PerfT m t b -> PerfT m t a
forall (m :: * -> *) t a b.
Monad m =>
PerfT m t a -> PerfT m t b -> PerfT m t b
forall (m :: * -> *) t a b.
Monad m =>
PerfT m t (a -> b) -> PerfT m t a -> PerfT m t b
forall (m :: * -> *) t a b c.
Monad m =>
(a -> b -> c) -> PerfT m t a -> PerfT m t b -> PerfT m t c
$cpure :: forall (m :: * -> *) t a. Monad m => a -> PerfT m t a
pure :: forall a. a -> PerfT m t a
$c<*> :: forall (m :: * -> *) t a b.
Monad m =>
PerfT m t (a -> b) -> PerfT m t a -> PerfT m t b
<*> :: forall a b. PerfT m t (a -> b) -> PerfT m t a -> PerfT m t b
$cliftA2 :: forall (m :: * -> *) t a b c.
Monad m =>
(a -> b -> c) -> PerfT m t a -> PerfT m t b -> PerfT m t c
liftA2 :: forall a b c.
(a -> b -> c) -> PerfT m t a -> PerfT m t b -> PerfT m t c
$c*> :: forall (m :: * -> *) t a b.
Monad m =>
PerfT m t a -> PerfT m t b -> PerfT m t b
*> :: forall a b. PerfT m t a -> PerfT m t b -> PerfT m t b
$c<* :: forall (m :: * -> *) t a b.
Monad m =>
PerfT m t a -> PerfT m t b -> PerfT m t a
<* :: forall a b. PerfT m t a -> PerfT m t b -> PerfT m t a
Applicative, Applicative (PerfT m t)
Applicative (PerfT m t) =>
(forall a b. PerfT m t a -> (a -> PerfT m t b) -> PerfT m t b)
-> (forall a b. PerfT m t a -> PerfT m t b -> PerfT m t b)
-> (forall a. a -> PerfT m t a)
-> Monad (PerfT m t)
forall a. a -> PerfT m t a
forall a b. PerfT m t a -> PerfT m t b -> PerfT m t b
forall a b. PerfT m t a -> (a -> PerfT m t b) -> PerfT m t b
forall (m :: * -> *).
Applicative m =>
(forall a b. m a -> (a -> m b) -> m b)
-> (forall a b. m a -> m b -> m b)
-> (forall a. a -> m a)
-> Monad m
forall (m :: * -> *) t. Monad m => Applicative (PerfT m t)
forall (m :: * -> *) t a. Monad m => a -> PerfT m t a
forall (m :: * -> *) t a b.
Monad m =>
PerfT m t a -> PerfT m t b -> PerfT m t b
forall (m :: * -> *) t a b.
Monad m =>
PerfT m t a -> (a -> PerfT m t b) -> PerfT m t b
$c>>= :: forall (m :: * -> *) t a b.
Monad m =>
PerfT m t a -> (a -> PerfT m t b) -> PerfT m t b
>>= :: forall a b. PerfT m t a -> (a -> PerfT m t b) -> PerfT m t b
$c>> :: forall (m :: * -> *) t a b.
Monad m =>
PerfT m t a -> PerfT m t b -> PerfT m t b
>> :: forall a b. PerfT m t a -> PerfT m t b -> PerfT m t b
$creturn :: forall (m :: * -> *) t a. Monad m => a -> PerfT m t a
return :: forall a. a -> PerfT m t a
Monad)

-- | The transformer over Identity
type Perf t a = PerfT Identity t a

instance (MonadIO m) => MonadIO (PerfT m t) where
  liftIO :: forall a. IO a -> PerfT m t a
liftIO = StateT (Measure m t, Map Text t) m a -> PerfT m t a
forall (m :: * -> *) t a.
StateT (Measure m t, Map Text t) m a -> PerfT m t a
PerfT (StateT (Measure m t, Map Text t) m a -> PerfT m t a)
-> (IO a -> StateT (Measure m t, Map Text t) m a)
-> IO a
-> PerfT m t a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IO a -> StateT (Measure m t, Map Text t) m a
forall a. IO a -> StateT (Measure m t, Map Text t) m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO

-- | Lift an application to a PerfT m, providing a label and a 'Measure'.
--
-- Measurements with the same label will be mappended
fap :: (MonadIO m, Semigroup t) => Text -> (a -> b) -> a -> PerfT m t b
fap :: forall (m :: * -> *) t a b.
(MonadIO m, Semigroup t) =>
Text -> (a -> b) -> a -> PerfT m t b
fap Text
label a -> b
f a
a =
  StateT (Measure m t, Map Text t) m b -> PerfT m t b
forall (m :: * -> *) t a.
StateT (Measure m t, Map Text t) m a -> PerfT m t a
PerfT (StateT (Measure m t, Map Text t) m b -> PerfT m t b)
-> StateT (Measure m t, Map Text t) m b -> PerfT m t b
forall a b. (a -> b) -> a -> b
$ do
    Measure m t
m <- (Measure m t, Map Text t) -> Measure m t
forall a b. (a, b) -> a
fst ((Measure m t, Map Text t) -> Measure m t)
-> StateT (Measure m t, Map Text t) m (Measure m t, Map Text t)
-> StateT (Measure m t, Map Text t) m (Measure m t)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> StateT (Measure m t, Map Text t) m (Measure m t, Map Text t)
forall s (m :: * -> *). MonadState s m => m s
get
    (t
t, b
fa) <- m (t, b) -> StateT (Measure m t, Map Text t) m (t, b)
forall (m :: * -> *) a.
Monad m =>
m a -> StateT (Measure m t, Map Text t) m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m (t, b) -> StateT (Measure m t, Map Text t) m (t, b))
-> m (t, b) -> StateT (Measure m t, Map Text t) m (t, b)
forall a b. (a -> b) -> a -> b
$ Measure m t -> forall a b. (a -> b) -> a -> m (t, b)
forall (m :: * -> *) t.
Measure m t -> forall a b. (a -> b) -> a -> m (t, b)
measure Measure m t
m a -> b
f a
a
    ((Measure m t, Map Text t) -> (Measure m t, Map Text t))
-> StateT (Measure m t, Map Text t) m ()
forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify (((Measure m t, Map Text t) -> (Measure m t, Map Text t))
 -> StateT (Measure m t, Map Text t) m ())
-> ((Measure m t, Map Text t) -> (Measure m t, Map Text t))
-> StateT (Measure m t, Map Text t) m ()
forall a b. (a -> b) -> a -> b
$ (Map Text t -> Map Text t)
-> (Measure m t, Map Text t) -> (Measure m t, Map Text t)
forall b c a. (b -> c) -> (a, b) -> (a, c)
forall (p :: * -> * -> *) b c a.
Bifunctor p =>
(b -> c) -> p a b -> p a c
second ((t -> t -> t) -> Text -> t -> Map Text t -> Map Text t
forall k a. Ord k => (a -> a -> a) -> k -> a -> Map k a -> Map k a
Map.insertWith t -> t -> t
forall a. Semigroup a => a -> a -> a
(<>) Text
label t
t)
    b -> StateT (Measure m t, Map Text t) m b
forall a. a -> StateT (Measure m t, Map Text t) m a
forall (m :: * -> *) a. Monad m => a -> m a
return b
fa
{-# INLINEABLE fap #-}

-- | Lift an application to a PerfT m, forcing the argument.
afap :: (NFData a, MonadIO m, Semigroup t) => Text -> (a -> b) -> a -> PerfT m t b
afap :: forall a (m :: * -> *) t b.
(NFData a, MonadIO m, Semigroup t) =>
Text -> (a -> b) -> a -> PerfT m t b
afap Text
label a -> b
f a
a = Text -> (a -> b) -> a -> PerfT m t b
forall (m :: * -> *) t a b.
(MonadIO m, Semigroup t) =>
Text -> (a -> b) -> a -> PerfT m t b
fap Text
label a -> b
f (a -> a
forall a. NFData a => a -> a
force a
a)
{-# INLINEABLE afap #-}

-- | Lift an application to a PerfT m, forcing argument and result.
ffap :: (NFData a, NFData b, MonadIO m, Semigroup t) => Text -> (a -> b) -> a -> PerfT m t b
ffap :: forall a b (m :: * -> *) t.
(NFData a, NFData b, MonadIO m, Semigroup t) =>
Text -> (a -> b) -> a -> PerfT m t b
ffap Text
label a -> b
f a
a = Text -> (a -> b) -> a -> PerfT m t b
forall (m :: * -> *) t a b.
(MonadIO m, Semigroup t) =>
Text -> (a -> b) -> a -> PerfT m t b
fap Text
label (b -> b
forall a. NFData a => a -> a
force (b -> b) -> (a -> b) -> a -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> b
f) (a -> a
forall a. NFData a => a -> a
force a
a)
{-# INLINEABLE ffap #-}

-- | Lift a number to a PerfT m, providing a label, function, and input.
--
-- Measurements with the same label will be added
fan :: (MonadIO m, Num t) => Text -> (a -> b) -> a -> PerfT m t b
fan :: forall (m :: * -> *) t a b.
(MonadIO m, Num t) =>
Text -> (a -> b) -> a -> PerfT m t b
fan Text
label a -> b
f a
a =
  StateT (Measure m t, Map Text t) m b -> PerfT m t b
forall (m :: * -> *) t a.
StateT (Measure m t, Map Text t) m a -> PerfT m t a
PerfT (StateT (Measure m t, Map Text t) m b -> PerfT m t b)
-> StateT (Measure m t, Map Text t) m b -> PerfT m t b
forall a b. (a -> b) -> a -> b
$ do
    Measure m t
m <- (Measure m t, Map Text t) -> Measure m t
forall a b. (a, b) -> a
fst ((Measure m t, Map Text t) -> Measure m t)
-> StateT (Measure m t, Map Text t) m (Measure m t, Map Text t)
-> StateT (Measure m t, Map Text t) m (Measure m t)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> StateT (Measure m t, Map Text t) m (Measure m t, Map Text t)
forall s (m :: * -> *). MonadState s m => m s
get
    (t
t, b
fa) <- m (t, b) -> StateT (Measure m t, Map Text t) m (t, b)
forall (m :: * -> *) a.
Monad m =>
m a -> StateT (Measure m t, Map Text t) m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m (t, b) -> StateT (Measure m t, Map Text t) m (t, b))
-> m (t, b) -> StateT (Measure m t, Map Text t) m (t, b)
forall a b. (a -> b) -> a -> b
$ Measure m t -> forall a b. (a -> b) -> a -> m (t, b)
forall (m :: * -> *) t.
Measure m t -> forall a b. (a -> b) -> a -> m (t, b)
measure Measure m t
m a -> b
f a
a
    ((Measure m t, Map Text t) -> (Measure m t, Map Text t))
-> StateT (Measure m t, Map Text t) m ()
forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify (((Measure m t, Map Text t) -> (Measure m t, Map Text t))
 -> StateT (Measure m t, Map Text t) m ())
-> ((Measure m t, Map Text t) -> (Measure m t, Map Text t))
-> StateT (Measure m t, Map Text t) m ()
forall a b. (a -> b) -> a -> b
$ (Map Text t -> Map Text t)
-> (Measure m t, Map Text t) -> (Measure m t, Map Text t)
forall b c a. (b -> c) -> (a, b) -> (a, c)
forall (p :: * -> * -> *) b c a.
Bifunctor p =>
(b -> c) -> p a b -> p a c
second ((t -> t -> t) -> Text -> t -> Map Text t -> Map Text t
forall k a. Ord k => (a -> a -> a) -> k -> a -> Map k a -> Map k a
Map.insertWith t -> t -> t
forall a. Num a => a -> a -> a
(+) Text
label t
t)
    b -> StateT (Measure m t, Map Text t) m b
forall a. a -> StateT (Measure m t, Map Text t) m a
forall (m :: * -> *) a. Monad m => a -> m a
return b
fa
{-# INLINEABLE fan #-}

-- | Lift a monadic value to a PerfT m, providing a label and a 'Measure'.
--
-- Measurements with the same label will be added
fam :: (MonadIO m, Semigroup t) => Text -> m a -> PerfT m t a
fam :: forall (m :: * -> *) t a.
(MonadIO m, Semigroup t) =>
Text -> m a -> PerfT m t a
fam Text
label m a
a =
  StateT (Measure m t, Map Text t) m a -> PerfT m t a
forall (m :: * -> *) t a.
StateT (Measure m t, Map Text t) m a -> PerfT m t a
PerfT (StateT (Measure m t, Map Text t) m a -> PerfT m t a)
-> StateT (Measure m t, Map Text t) m a -> PerfT m t a
forall a b. (a -> b) -> a -> b
$ do
    Measure m t
m <- (Measure m t, Map Text t) -> Measure m t
forall a b. (a, b) -> a
fst ((Measure m t, Map Text t) -> Measure m t)
-> StateT (Measure m t, Map Text t) m (Measure m t, Map Text t)
-> StateT (Measure m t, Map Text t) m (Measure m t)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> StateT (Measure m t, Map Text t) m (Measure m t, Map Text t)
forall s (m :: * -> *). MonadState s m => m s
get
    (t
t, !m a
ma) <- m (t, m a) -> StateT (Measure m t, Map Text t) m (t, m a)
forall (m :: * -> *) a.
Monad m =>
m a -> StateT (Measure m t, Map Text t) m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m (t, m a) -> StateT (Measure m t, Map Text t) m (t, m a))
-> m (t, m a) -> StateT (Measure m t, Map Text t) m (t, m a)
forall a b. (a -> b) -> a -> b
$ Measure m t -> forall a b. (a -> b) -> a -> m (t, b)
forall (m :: * -> *) t.
Measure m t -> forall a b. (a -> b) -> a -> m (t, b)
measure Measure m t
m (m a -> () -> m a
forall a b. a -> b -> a
const m a
a) ()
    ((Measure m t, Map Text t) -> (Measure m t, Map Text t))
-> StateT (Measure m t, Map Text t) m ()
forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify (((Measure m t, Map Text t) -> (Measure m t, Map Text t))
 -> StateT (Measure m t, Map Text t) m ())
-> ((Measure m t, Map Text t) -> (Measure m t, Map Text t))
-> StateT (Measure m t, Map Text t) m ()
forall a b. (a -> b) -> a -> b
$ (Map Text t -> Map Text t)
-> (Measure m t, Map Text t) -> (Measure m t, Map Text t)
forall b c a. (b -> c) -> (a, b) -> (a, c)
forall (p :: * -> * -> *) b c a.
Bifunctor p =>
(b -> c) -> p a b -> p a c
second ((t -> t -> t) -> Text -> t -> Map Text t -> Map Text t
forall k a. Ord k => (a -> a -> a) -> k -> a -> Map k a -> Map k a
Map.insertWith t -> t -> t
forall a. Semigroup a => a -> a -> a
(<>) Text
label t
t)
    m a -> StateT (Measure m t, Map Text t) m a
forall (m :: * -> *) a.
Monad m =>
m a -> StateT (Measure m t, Map Text t) m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift m a
ma
{-# INLINEABLE fam #-}

-- | lift a pure, unnamed function application to PerfT
(|$|) :: (Semigroup t) => (a -> b) -> a -> PerfT IO t b
|$| :: forall t a b. Semigroup t => (a -> b) -> a -> PerfT IO t b
(|$|) a -> b
f a
a = Text -> (a -> b) -> a -> PerfT IO t b
forall (m :: * -> *) t a b.
(MonadIO m, Semigroup t) =>
Text -> (a -> b) -> a -> PerfT m t b
fap Text
"" a -> b
f a
a
{-# INLINEABLE (|$|) #-}

-- | lift a monadic, unnamed function application to PerfT
($|) :: (Semigroup t) => IO a -> PerfT IO t a
$| :: forall t a. Semigroup t => IO a -> PerfT IO t a
($|) IO a
a = Text -> IO a -> PerfT IO t a
forall (m :: * -> *) t a.
(MonadIO m, Semigroup t) =>
Text -> m a -> PerfT m t a
fam Text
"" IO a
a
{-# INLINEABLE ($|) #-}

-- | lift an unnamed numeric measure to PerfT
(|+|) :: (Num t) => (a -> b) -> a -> PerfT IO t b
|+| :: forall t a b. Num t => (a -> b) -> a -> PerfT IO t b
(|+|) a -> b
f a
a = Text -> (a -> b) -> a -> PerfT IO t b
forall (m :: * -> *) t a b.
(MonadIO m, Num t) =>
Text -> (a -> b) -> a -> PerfT m t b
fan Text
"" a -> b
f a
a
{-# INLINEABLE (|+|) #-}

-- | Run the performance measure, returning (computational result, measurement).
runPerfT :: (Functor m) => Measure m t -> PerfT m t a -> m (a, Map.Map Text t)
runPerfT :: forall (m :: * -> *) t a.
Functor m =>
Measure m t -> PerfT m t a -> m (a, Map Text t)
runPerfT Measure m t
m PerfT m t a
p = ((a, (Measure m t, Map Text t)) -> (a, Map Text t))
-> m (a, (Measure m t, Map Text t)) -> m (a, Map Text t)
forall a b. (a -> b) -> m a -> m b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (((Measure m t, Map Text t) -> Map Text t)
-> (a, (Measure m t, Map Text t)) -> (a, Map Text t)
forall b c a. (b -> c) -> (a, b) -> (a, c)
forall (p :: * -> * -> *) b c a.
Bifunctor p =>
(b -> c) -> p a b -> p a c
second (Measure m t, Map Text t) -> Map Text t
forall a b. (a, b) -> b
snd) (m (a, (Measure m t, Map Text t)) -> m (a, Map Text t))
-> (StateT (Measure m t, Map Text t) m a
    -> m (a, (Measure m t, Map Text t)))
-> StateT (Measure m t, Map Text t) m a
-> m (a, Map Text t)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (StateT (Measure m t, Map Text t) m a
 -> (Measure m t, Map Text t) -> m (a, (Measure m t, Map Text t)))
-> (Measure m t, Map Text t)
-> StateT (Measure m t, Map Text t) m a
-> m (a, (Measure m t, Map Text t))
forall a b c. (a -> b -> c) -> b -> a -> c
flip StateT (Measure m t, Map Text t) m a
-> (Measure m t, Map Text t) -> m (a, (Measure m t, Map Text t))
forall s (m :: * -> *) a. StateT s m a -> s -> m (a, s)
runStateT (Measure m t
m, Map Text t
forall k a. Map k a
Map.empty) (StateT (Measure m t, Map Text t) m a -> m (a, Map Text t))
-> StateT (Measure m t, Map Text t) m a -> m (a, Map Text t)
forall a b. (a -> b) -> a -> b
$ PerfT m t a -> StateT (Measure m t, Map Text t) m a
forall (m :: * -> *) t a.
PerfT m t a -> StateT (Measure m t, Map Text t) m a
measurePerf PerfT m t a
p
{-# INLINEABLE runPerfT #-}

-- | Consume the PerfT layer and return the original monadic result.
-- Fingers crossed, PerfT structure should be completely compiled away.
evalPerfT :: (Monad m) => Measure m t -> PerfT m t a -> m a
evalPerfT :: forall (m :: * -> *) t a.
Monad m =>
Measure m t -> PerfT m t a -> m a
evalPerfT Measure m t
m PerfT m t a
p = ((a, (Measure m t, Map Text t)) -> a)
-> m (a, (Measure m t, Map Text t)) -> m a
forall a b. (a -> b) -> m a -> m b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (a, (Measure m t, Map Text t)) -> a
forall a b. (a, b) -> a
fst (m (a, (Measure m t, Map Text t)) -> m a)
-> (StateT (Measure m t, Map Text t) m a
    -> m (a, (Measure m t, Map Text t)))
-> StateT (Measure m t, Map Text t) m a
-> m a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (StateT (Measure m t, Map Text t) m a
 -> (Measure m t, Map Text t) -> m (a, (Measure m t, Map Text t)))
-> (Measure m t, Map Text t)
-> StateT (Measure m t, Map Text t) m a
-> m (a, (Measure m t, Map Text t))
forall a b c. (a -> b -> c) -> b -> a -> c
flip StateT (Measure m t, Map Text t) m a
-> (Measure m t, Map Text t) -> m (a, (Measure m t, Map Text t))
forall s (m :: * -> *) a. StateT s m a -> s -> m (a, s)
runStateT (Measure m t
m, Map Text t
forall k a. Map k a
Map.empty) (StateT (Measure m t, Map Text t) m a -> m a)
-> StateT (Measure m t, Map Text t) m a -> m a
forall a b. (a -> b) -> a -> b
$ PerfT m t a -> StateT (Measure m t, Map Text t) m a
forall (m :: * -> *) t a.
PerfT m t a -> StateT (Measure m t, Map Text t) m a
measurePerf PerfT m t a
p
{-# INLINEABLE evalPerfT #-}

-- | Consume a PerfT layer and return the measurement.
execPerfT :: (Monad m) => Measure m t -> PerfT m t a -> m (Map.Map Text t)
execPerfT :: forall (m :: * -> *) t a.
Monad m =>
Measure m t -> PerfT m t a -> m (Map Text t)
execPerfT Measure m t
m PerfT m t a
p = ((Measure m t, Map Text t) -> Map Text t)
-> m (Measure m t, Map Text t) -> m (Map Text t)
forall a b. (a -> b) -> m a -> m b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Measure m t, Map Text t) -> Map Text t
forall a b. (a, b) -> b
snd (m (Measure m t, Map Text t) -> m (Map Text t))
-> (StateT (Measure m t, Map Text t) m a
    -> m (Measure m t, Map Text t))
-> StateT (Measure m t, Map Text t) m a
-> m (Map Text t)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (StateT (Measure m t, Map Text t) m a
 -> (Measure m t, Map Text t) -> m (Measure m t, Map Text t))
-> (Measure m t, Map Text t)
-> StateT (Measure m t, Map Text t) m a
-> m (Measure m t, Map Text t)
forall a b c. (a -> b -> c) -> b -> a -> c
flip StateT (Measure m t, Map Text t) m a
-> (Measure m t, Map Text t) -> m (Measure m t, Map Text t)
forall (m :: * -> *) s a. Monad m => StateT s m a -> s -> m s
execStateT (Measure m t
m, Map Text t
forall k a. Map k a
Map.empty) (StateT (Measure m t, Map Text t) m a -> m (Map Text t))
-> StateT (Measure m t, Map Text t) m a -> m (Map Text t)
forall a b. (a -> b) -> a -> b
$ PerfT m t a -> StateT (Measure m t, Map Text t) m a
forall (m :: * -> *) t a.
PerfT m t a -> StateT (Measure m t, Map Text t) m a
measurePerf PerfT m t a
p
{-# INLINEABLE execPerfT #-}

-- | run a PerfT and also calculate performance over the entire computation
outer :: (MonadIO m, Semigroup s) => Text -> Measure m s -> Measure m t -> PerfT m t a -> m (a, (Map.Map Text s, Map.Map Text t))
outer :: forall (m :: * -> *) s t a.
(MonadIO m, Semigroup s) =>
Text
-> Measure m s
-> Measure m t
-> PerfT m t a
-> m (a, (Map Text s, Map Text t))
outer Text
label Measure m s
outerm Measure m t
meas PerfT m t a
p =
  (\((a
a, Map Text t
m), Map Text s
m') -> (a
a, (Map Text s
m', Map Text t
m)))
    (((a, Map Text t), Map Text s) -> (a, (Map Text s, Map Text t)))
-> m ((a, Map Text t), Map Text s)
-> m (a, (Map Text s, Map Text t))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Measure m s
-> PerfT m s (a, Map Text t) -> m ((a, Map Text t), Map Text s)
forall (m :: * -> *) t a.
Functor m =>
Measure m t -> PerfT m t a -> m (a, Map Text t)
runPerfT
      Measure m s
outerm
      (Text -> m (a, Map Text t) -> PerfT m s (a, Map Text t)
forall (m :: * -> *) t a.
(MonadIO m, Semigroup t) =>
Text -> m a -> PerfT m t a
fam Text
label (Measure m t -> PerfT m t a -> m (a, Map Text t)
forall (m :: * -> *) t a.
Functor m =>
Measure m t -> PerfT m t a -> m (a, Map Text t)
runPerfT Measure m t
meas PerfT m t a
p))

-- | run a PerfT and calculate excess performance over the entire computation
slop :: (MonadIO m, Num t, Semigroup t) => Text -> Measure m t -> PerfT m t a -> m (a, Map.Map Text t)
slop :: forall (m :: * -> *) t a.
(MonadIO m, Num t, Semigroup t) =>
Text -> Measure m t -> PerfT m t a -> m (a, Map Text t)
slop Text
l Measure m t
meas PerfT m t a
p =
  (\((a
a, Map Text t
m), Map Text t
m') -> (a
a, Map Text t
m Map Text t -> Map Text t -> Map Text t
forall a. Semigroup a => a -> a -> a
<> Text -> t -> Map Text t -> Map Text t
forall k a. Ord k => k -> a -> Map k a -> Map k a
Map.insert Text
"slop" (Map Text t
m' Map Text t -> Text -> t
forall k a. Ord k => Map k a -> k -> a
Map.! Text
l t -> t -> t
forall a. Num a => a -> a -> a
- (t -> t -> t) -> t -> Map Text t -> t
forall a b k. (a -> b -> a) -> a -> Map k b -> a
Map.foldl' t -> t -> t
forall a. Num a => a -> a -> a
(+) t
0 Map Text t
m) Map Text t
m'))
    (((a, Map Text t), Map Text t) -> (a, Map Text t))
-> m ((a, Map Text t), Map Text t) -> m (a, Map Text t)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Measure m t
-> PerfT m t (a, Map Text t) -> m ((a, Map Text t), Map Text t)
forall (m :: * -> *) t a.
Functor m =>
Measure m t -> PerfT m t a -> m (a, Map Text t)
runPerfT
      Measure m t
meas
      (Text -> m (a, Map Text t) -> PerfT m t (a, Map Text t)
forall (m :: * -> *) t a.
(MonadIO m, Semigroup t) =>
Text -> m a -> PerfT m t a
fam Text
l (Measure m t -> PerfT m t a -> m (a, Map Text t)
forall (m :: * -> *) t a.
Functor m =>
Measure m t -> PerfT m t a -> m (a, Map Text t)
runPerfT Measure m t
meas PerfT m t a
p))

-- | run a multi PerfT and calculate excess performance over the entire computation
slops :: (MonadIO m, Num t, Semigroup t) => Int -> Measure m t -> PerfT m [t] a -> m (a, (Map.Map Text t, Map.Map Text [t]))
slops :: forall (m :: * -> *) t a.
(MonadIO m, Num t, Semigroup t) =>
Int
-> Measure m t
-> PerfT m [t] a
-> m (a, (Map Text t, Map Text [t]))
slops Int
n Measure m t
meas PerfT m [t] a
p =
  (\((a
a, Map Text [t]
ms), Map Text t
m') -> (a
a, (Text -> t -> Map Text t -> Map Text t
forall k a. Ord k => k -> a -> Map k a -> Map k a
Map.insert Text
"slop" (Map Text t
m' Map Text t -> Text -> t
forall k a. Ord k => Map k a -> k -> a
Map.! Text
"outer" t -> t -> t
forall a. Num a => a -> a -> a
- (t -> t -> t) -> t -> Map Text t -> t
forall a b k. (a -> b -> a) -> a -> Map k b -> a
Map.foldl' t -> t -> t
forall a. Num a => a -> a -> a
(+) t
0 (([t] -> t) -> Map Text [t] -> Map Text t
forall a b. (a -> b) -> Map Text a -> Map Text b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [t] -> t
forall a. Num a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum Map Text [t]
ms)) Map Text t
m', Map Text [t]
ms)))
    (((a, Map Text [t]), Map Text t)
 -> (a, (Map Text t, Map Text [t])))
-> m ((a, Map Text [t]), Map Text t)
-> m (a, (Map Text t, Map Text [t]))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Measure m t
-> PerfT m t (a, Map Text [t]) -> m ((a, Map Text [t]), Map Text t)
forall (m :: * -> *) t a.
Functor m =>
Measure m t -> PerfT m t a -> m (a, Map Text t)
runPerfT
      Measure m t
meas
      (Text -> m (a, Map Text [t]) -> PerfT m t (a, Map Text [t])
forall (m :: * -> *) t a.
(MonadIO m, Semigroup t) =>
Text -> m a -> PerfT m t a
fam Text
"outer" (Measure m [t] -> PerfT m [t] a -> m (a, Map Text [t])
forall (m :: * -> *) t a.
Functor m =>
Measure m t -> PerfT m t a -> m (a, Map Text t)
runPerfT (Int -> Measure m t -> Measure m [t]
forall (m :: * -> *) t.
Applicative m =>
Int -> Measure m t -> Measure m [t]
repeated Int
n Measure m t
meas) PerfT m [t] a
p))