diff --git a/bench/bench.hs b/bench/bench.hs
--- a/bench/bench.hs
+++ b/bench/bench.hs
@@ -12,12 +12,14 @@
 import Online.Averages
 import Online.Medians
 import Options.Generic
-import NumHask.Prelude hiding ((%))
-import Perf
+import NumHask.Prelude hiding ((%), fromIntegral)
+import Protolude (fromIntegral)
+import Perf hiding (zero, Additive)
 import Formatting
 import qualified Data.Text as Text
 import qualified Control.Foldl as L
 import Data.Scientific
+import Data.TDigest
 
 data Opts = Opts
   { runs :: Maybe Int -- <?> "number of runs"
@@ -26,6 +28,22 @@
 
 instance ParseRecord Opts
 
+-- | compute deciles
+--
+-- > c5 <- decile 5 <$> ticks n f a
+--
+deciles :: (Functor f, Foldable f) => Int -> f Cycle -> [Double]
+deciles n xs =
+  (\x -> fromMaybe 0 $ quantile x (tdigest (fromIntegral <$> xs) :: TDigest 25)) <$>
+  ((/ fromIntegral n) . fromIntegral <$> [0 .. n]) :: [Double]
+
+-- | compute a percentile
+--
+-- > c <- percentile 0.4 . fst <$> ticks n f a
+--
+percentile :: (Functor f, Foldable f) => Double -> f Cycle -> Double
+percentile p xs = fromMaybe 0 $ quantile p (tdigest (fromIntegral <$> xs) :: TDigest 25)
+
 expt' :: Int -> Format r (Scientific -> r)
 expt' x = scifmt Exponent (Just x)
 
@@ -71,7 +89,7 @@
 formatRun cs label =
     sformat
           ((right 24 ' ' %. stext) % stext %
-           (left 7 ' ' %. expt' 3) % " cycles")
+           (left 9 ' ' %. expt' 3) % " cycles")
           label
           (Text.intercalate " " $ sformat (left 7 ' ' %. expt' 3) <$>
            (\x -> scientific (fromIntegral x) 0) <$> take 5 cs)
diff --git a/online.cabal b/online.cabal
--- a/online.cabal
+++ b/online.cabal
@@ -2,10 +2,10 @@
 --
 -- see: https://github.com/sol/hpack
 --
--- hash: 160bd8de21b13879993819afe4d9b4640f9183a6e979143c22b2aaa8e4510e31
+-- hash: 5a5f633300efb3112bf98d43704d99a8f5c77499334e49e51687fa4d33f3b1d0
 
 name:           online
-version:        0.2.1.0
+version:        0.2.2.0
 synopsis:       online statistics
 description:    transformation of statistics to online algorithms
 category:       statistics
@@ -31,11 +31,11 @@
   hs-source-dirs:
       src
   default-extensions: NegativeLiterals NoImplicitPrelude OverloadedStrings UnicodeSyntax
-  ghc-options: -Wall
+  ghc-options: -Wall -Wcompat -Wincomplete-record-updates -Wincomplete-uni-patterns -Wredundant-constraints
   build-depends:
       base >=4.7 && <5
     , foldl
-    , numhask
+    , numhask-prelude
     , protolude
     , tdigest
     , vector
@@ -53,18 +53,19 @@
   main-is: bench.hs
   hs-source-dirs:
       bench
-  default-extensions: NegativeLiterals NoImplicitPrelude OverloadedStrings UnicodeSyntax BangPatterns BinaryLiterals DeriveFoldable DeriveFunctor DeriveGeneric DeriveTraversable DisambiguateRecordFields EmptyCase FlexibleContexts FlexibleInstances FunctionalDependencies GADTSyntax InstanceSigs KindSignatures LambdaCase MonadComprehensions MultiParamTypeClasses MultiWayIf ParallelListComp PartialTypeSignatures PatternSynonyms RankNTypes RecordWildCards RecursiveDo ScopedTypeVariables TupleSections TypeFamilies TypeOperators
+  default-extensions: NegativeLiterals NoImplicitPrelude OverloadedStrings UnicodeSyntax
   ghc-options: -O2 -funbox-strict-fields -fforce-recomp -threaded -rtsopts -with-rtsopts=-N
   build-depends:
       base >=4.7 && <5
     , foldl
     , formatting
-    , numhask
+    , numhask-prelude
     , online
     , optparse-generic
     , perf
     , protolude
     , scientific
+    , tdigest
     , text
   other-modules:
       Paths_online
@@ -79,7 +80,6 @@
   build-depends:
       base >=4.7 && <5
     , doctest
-    , online
     , protolude
     , tasty
   other-modules:
diff --git a/readme.md b/readme.md
--- a/readme.md
+++ b/readme.md
@@ -61,18 +61,18 @@
 
     sum to 1,000
     run                       first     2nd     3rd     4th     5th  40th %
-    sumInt [0..]             8.69e3  1.59e3  1.54e3  1.60e3  1.64e3 1.57e3 cycles
-    sumDouble [0..]          3.00e5  2.82e5  3.27e5  2.99e5  2.61e5 9.38e4 cycles
-    sumPoly [0..]            9.34e4  1.05e5  1.09e5  1.18e5  1.64e5 7.81e4 cycles
-    sum Int                  1.67e4  1.17e4  1.16e4  1.17e4  1.16e4 1.17e4 cycles
-    sum Double               2.63e4  1.18e4  1.17e4  1.16e4  1.16e4 1.16e4 cycles
-    sum Poly                 1.28e4  1.18e4  1.17e4  1.17e4  1.18e4 1.17e4 cycles
-    fold sum                 1.23e4  1.19e4  1.18e4  1.17e4  1.18e4 1.18e4 cycles
-    fold av                  1.23e4  1.18e4  1.18e4  1.18e4  1.18e4 1.18e4 cycles
-    fold ma                  1.24e4  1.19e4  1.20e4  1.19e4  1.19e4 1.19e4 cycles
-    fold std                 2.04e5  1.15e5  6.14e5  1.16e5  1.16e5 1.12e5 cycles
-    fold maL1                9.11e4  8.32e4  1.27e5  3.34e5  1.04e5 1.02e5 cycles
-    fold absmaL1             6.82e4  6.71e4  6.64e4  6.66e4  2.97e5 6.65e4 cycles
+    sumInt [0..]            6.064e3 1.746e3 1.560e3 1.540e3 1.626e3  1.544e3 cycles
+    sumDouble [0..]         7.835e5 3.032e5 3.104e5 2.837e5 3.051e5  8.957e4 cycles
+    sumPoly [0..]           1.139e5 7.660e4 7.638e4 7.648e4 7.636e4  7.674e4 cycles
+    sum Int                 1.601e4 1.186e4 1.167e4 1.158e4 1.176e4  1.168e4 cycles
+    sum Double              2.756e4 1.189e4 1.158e4 1.163e4 1.158e4  1.159e4 cycles
+    sum Poly                1.170e4 1.172e4 1.163e4 1.166e4 1.158e4  1.164e4 cycles
+    fold sum                1.177e4 1.174e4 1.178e4 1.185e4 1.177e4  1.175e4 cycles
+    fold av                 2.935e4 1.190e4 1.181e4 1.182e4 1.177e4  1.181e4 cycles
+    fold ma                 1.289e4 1.202e4 1.205e4 1.203e4 1.206e4  1.201e4 cycles
+    fold std                2.052e5 1.210e5 7.236e5 1.364e5 1.348e5  1.324e5 cycles
+    fold maL1               8.218e4 1.192e5 1.052e5 2.567e5 1.168e5  7.856e4 cycles
+    fold absmaL1            3.405e5 5.966e4 5.976e4 6.025e4 5.939e4  5.975e4 cycles
 
 recipe
 ======
diff --git a/src/Online/Averages.hs b/src/Online/Averages.hs
--- a/src/Online/Averages.hs
+++ b/src/Online/Averages.hs
@@ -27,10 +27,13 @@
   { _averager :: (a, b)
   }
 
+instance (Semigroup a, Monoid b) => Semigroup (Averager a b) where
+  (Averager (s, c)) <> (Averager (s', c')) =
+    Averager (s <> s', c <> c')
+
 instance (Monoid a, Monoid b) => Monoid (Averager a b) where
   mempty = Averager (mempty, mempty)
-  mappend (Averager (s, c)) (Averager (s', c')) =
-    Averager (mappend s s', mappend c c')
+  mappend = (<>)
 
 -- | online takes a function and turns it into a `Control.Foldl.Fold` where the step is an incremental update of the (isomorphic) statistic.
 online :: (Field b) => (a -> b) -> (b -> b) -> Fold a b
diff --git a/stack.yaml b/stack.yaml
--- a/stack.yaml
+++ b/stack.yaml
@@ -1,6 +1,12 @@
-resolver: nightly-2017-11-22
+resolver: nightly-2018-04-05
 
 packages:
   - '.'
 
-extra-deps: []
+extra-deps:
+  - numhask-0.2.0.0
+  - numhask-prelude-0.0.1.0
+  - perf-0.4.0.0
+  - tdigest-0.1
+
+allow-newer: true
