{-# LANGUAGE BangPatterns               #-}
{-# LANGUAGE DefaultSignatures          #-}
{-# LANGUAGE DeriveDataTypeable         #-}
{-# LANGUAGE DeriveFoldable             #-}
{-# LANGUAGE DeriveFunctor              #-}
{-# LANGUAGE DeriveGeneric              #-}
{-# LANGUAGE DeriveTraversable          #-}
{-# LANGUAGE DerivingStrategies         #-}
{-# LANGUAGE FlexibleInstances          #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE MultiParamTypeClasses      #-}
{-# LANGUAGE RankNTypes                 #-}
{-# LANGUAGE TemplateHaskell            #-}
{-# LANGUAGE TypeFamilies               #-}
-- |
-- Module     : Data.Monoid.Statistics
-- Copyright  : Copyright (c) 2010,2017, Alexey Khudyakov <alexey.skladnoy@gmail.com>
-- License    : BSD3
-- Maintainer : Alexey Khudyakov <alexey.skladnoy@gmail.com>
-- Stability  : experimental
--
module Data.Monoid.Statistics.Class
  ( -- * Monoid Type class and helpers
    StatMonoid(..)
  , reduceSample
  , reduceSampleVec
    -- * Ad-hoc type classes for select statistics
    -- $adhoc
  , CalcCount(..)
  , CalcMean(..)
  , HasMean(..)
  , CalcVariance(..)
  , HasVariance(..)
  , CalcViaHas(..)
    -- * Exception handling
  , Partial(..)
  , partial
  , SampleError(..)
    -- * Data types
  , Pair(..)
  ) where

import           Control.Exception
import           Control.Monad.Catch (MonadThrow(..))
import           Data.Data           (Typeable,Data)
import           Data.Monoid
import           Data.Vector.Unboxed          (Unbox)
import           Data.Vector.Unboxed.Deriving (derivingUnbox)
import qualified Data.Foldable       as F
import qualified Data.Vector.Generic as G
import           Numeric.Sum
import GHC.Stack    (HasCallStack)
import GHC.Generics (Generic)


-- | This type class is used to express parallelizable constant space
--   algorithms for calculation of statistics. /Statistic/ is function
--   of type @[a]→b@ which does not depend on order of elements. (for
--   example: mean, sum, number of elements, variance, etc).
--
--   For many statistics it's possible to possible to construct
--   constant space algorithm which is expressed as fold. Additionally
--   it's usually possible to write function which combine state of
--   fold accumulator to get statistic for union of two samples.
--
--   Thus for such algorithm we have value which corresponds to empty
--   sample, function which which corresponds to merging of two
--   samples, and single step of fold. Last one allows to evaluate
--   statistic given data sample and first two form a monoid and allow
--   parallelization: split data into parts, build estimate for each
--   by folding and then merge them using mappend.
--
--   Instance must satisfy following laws. If floating point
--   arithmetics is used then equality should be understood as
--   approximate.
--
--   > 1. addValue (addValue y mempty) x  == addValue mempty x <> addValue mempty y
--   > 2. x <> y == y <> x
class Monoid m => StatMonoid m a where
  -- | Add one element to monoid accumulator. It's step of fold.
  addValue :: m -> a -> m
  addValue m
m a
a = m
m m -> m -> m
forall a. Semigroup a => a -> a -> a
<> a -> m
forall m a. StatMonoid m a => a -> m
singletonMonoid a
a
  {-# INLINE addValue #-}
  -- | State of accumulator corresponding to 1-element sample.
  singletonMonoid :: a -> m
  singletonMonoid = m -> a -> m
forall m a. StatMonoid m a => m -> a -> m
addValue m
forall a. Monoid a => a
mempty
  {-# INLINE singletonMonoid #-}
  {-# MINIMAL addValue | singletonMonoid #-}

-- | Calculate statistic over 'Foldable'. It's implemented in terms of
--   foldl'. Note that in cases when accumulator is immediately
--   consumed by polymorphic function such as 'callMeam' its type
--   becomes ambiguous. @TypeApplication@ then could be used to
--   disambiguate.
--
-- >>> reduceSample @Mean [1,2,3,4]
-- MeanKBN 4 (KBNSum 10.0 0.0)
-- >>> calcMean $ reduceSample @Mean [1,2,3,4] :: Maybe Double
-- Just 2.5
reduceSample :: forall m a f. (StatMonoid m a, F.Foldable f) => f a -> m
reduceSample :: f a -> m
reduceSample = (m -> a -> m) -> m -> f a -> m
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
F.foldl' m -> a -> m
forall m a. StatMonoid m a => m -> a -> m
addValue m
forall a. Monoid a => a
mempty

-- | Calculate statistic over vector. Works in same was as
-- 'reduceSample' but works for vectors.
reduceSampleVec :: forall m a v. (StatMonoid m a, G.Vector v a) => v a -> m
reduceSampleVec :: v a -> m
reduceSampleVec = (m -> a -> m) -> m -> v a -> m
forall (v :: * -> *) b a.
Vector v b =>
(a -> b -> a) -> a -> v b -> a
G.foldl' m -> a -> m
forall m a. StatMonoid m a => m -> a -> m
addValue m
forall a. Monoid a => a
mempty
{-# INLINE reduceSampleVec #-}

instance ( StatMonoid m1 a
         , StatMonoid m2 a
         ) => StatMonoid (m1,m2) a where
  addValue :: (m1, m2) -> a -> (m1, m2)
addValue (!m1
m1, !m2
m2) a
a =
    let !m1' :: m1
m1' = m1 -> a -> m1
forall m a. StatMonoid m a => m -> a -> m
addValue m1
m1 a
a
        !m2' :: m2
m2' = m2 -> a -> m2
forall m a. StatMonoid m a => m -> a -> m
addValue m2
m2 a
a
    in (m1
m1', m2
m2')
  singletonMonoid :: a -> (m1, m2)
singletonMonoid a
a = ( a -> m1
forall m a. StatMonoid m a => a -> m
singletonMonoid a
a
                      , a -> m2
forall m a. StatMonoid m a => a -> m
singletonMonoid a
a
                      )

instance ( StatMonoid m1 a
         , StatMonoid m2 a
         , StatMonoid m3 a
         ) => StatMonoid (m1,m2,m3) a where
  addValue :: (m1, m2, m3) -> a -> (m1, m2, m3)
addValue (!m1
m1, !m2
m2, !m3
m3) a
a =
    let !m1' :: m1
m1' = m1 -> a -> m1
forall m a. StatMonoid m a => m -> a -> m
addValue m1
m1 a
a
        !m2' :: m2
m2' = m2 -> a -> m2
forall m a. StatMonoid m a => m -> a -> m
addValue m2
m2 a
a
        !m3' :: m3
m3' = m3 -> a -> m3
forall m a. StatMonoid m a => m -> a -> m
addValue m3
m3 a
a
    in (m1
m1', m2
m2', m3
m3')
  singletonMonoid :: a -> (m1, m2, m3)
singletonMonoid a
a = ( a -> m1
forall m a. StatMonoid m a => a -> m
singletonMonoid a
a
                      , a -> m2
forall m a. StatMonoid m a => a -> m
singletonMonoid a
a
                      , a -> m3
forall m a. StatMonoid m a => a -> m
singletonMonoid a
a
                      )

instance ( StatMonoid m1 a
         , StatMonoid m2 a
         , StatMonoid m3 a
         , StatMonoid m4 a
         ) => StatMonoid (m1,m2,m3,m4) a where
  addValue :: (m1, m2, m3, m4) -> a -> (m1, m2, m3, m4)
addValue (!m1
m1, !m2
m2, !m3
m3, !m4
m4) a
a =
    let !m1' :: m1
m1' = m1 -> a -> m1
forall m a. StatMonoid m a => m -> a -> m
addValue m1
m1 a
a
        !m2' :: m2
m2' = m2 -> a -> m2
forall m a. StatMonoid m a => m -> a -> m
addValue m2
m2 a
a
        !m3' :: m3
m3' = m3 -> a -> m3
forall m a. StatMonoid m a => m -> a -> m
addValue m3
m3 a
a
        !m4' :: m4
m4' = m4 -> a -> m4
forall m a. StatMonoid m a => m -> a -> m
addValue m4
m4 a
a
    in (m1
m1', m2
m2', m3
m3', m4
m4')
  singletonMonoid :: a -> (m1, m2, m3, m4)
singletonMonoid a
a = ( a -> m1
forall m a. StatMonoid m a => a -> m
singletonMonoid a
a
                      , a -> m2
forall m a. StatMonoid m a => a -> m
singletonMonoid a
a
                      , a -> m3
forall m a. StatMonoid m a => a -> m
singletonMonoid a
a
                      , a -> m4
forall m a. StatMonoid m a => a -> m
singletonMonoid a
a
                      )

instance (Num a, a ~ a') => StatMonoid (Sum a) a' where
  singletonMonoid :: a' -> Sum a
singletonMonoid = a' -> Sum a
forall a. a -> Sum a
Sum

instance (Num a, a ~ a') => StatMonoid (Product a) a' where
  singletonMonoid :: a' -> Product a
singletonMonoid = a' -> Product a
forall a. a -> Product a
Product

instance Real a => StatMonoid KahanSum a where
  addValue :: KahanSum -> a -> KahanSum
addValue KahanSum
m a
x = KahanSum -> Double -> KahanSum
forall s. Summation s => s -> Double -> s
add KahanSum
m (a -> Double
forall a b. (Real a, Fractional b) => a -> b
realToFrac a
x)
  {-# INLINE addValue #-}

instance Real a => StatMonoid KBNSum a where
  addValue :: KBNSum -> a -> KBNSum
addValue KBNSum
m a
x = KBNSum -> Double -> KBNSum
forall s. Summation s => s -> Double -> s
add KBNSum
m (a -> Double
forall a b. (Real a, Fractional b) => a -> b
realToFrac a
x)
  {-# INLINE addValue #-}

instance Real a => StatMonoid KB2Sum a where
  addValue :: KB2Sum -> a -> KB2Sum
addValue KB2Sum
m a
x = KB2Sum -> Double -> KB2Sum
forall s. Summation s => s -> Double -> s
add KB2Sum
m (a -> Double
forall a b. (Real a, Fractional b) => a -> b
realToFrac a
x)
  {-# INLINE addValue #-}


----------------------------------------------------------------
-- Ad-hoc type class
----------------------------------------------------------------

-- $adhoc
--
-- Type classes defined here allows to extract common statistics from
-- estimators. it's assumed that quantities in question are already
-- computed so extraction is cheap.
--
--
-- ==== Error handling
--
-- Computation of statistics may fail. For example mean is not defined
-- for an empty sample. @Maybe@ could be seen as easy way to handle
-- this situation. But in many cases most convenient way to handle
-- failure is to throw an exception. So failure is encoded by using
-- polymorphic function of type @MonadThrow m ⇒ a → m X@.
--
-- Maybe types has instance, such as 'Maybe', 'Either'
-- 'Control.Exception.SomeException', 'IO' and most transformers
-- wrapping it. Notably this library defines 'Partial' monad which
-- allows to convert failures to exception in pure setting.
--
-- >>> calcMean $ reduceSample @Mean []
-- *** Exception: EmptySample "Data.Monoid.Statistics.Numeric.MeanKBN: calcMean"
--
-- >>> calcMean $ reduceSample @Mean [] :: Maybe Double
-- Nothing
--
-- >>> import Control.Exception
-- >>> calcMean $ reduceSample @Mean [] :: Either SomeException Double
-- Left (EmptySample "Data.Monoid.Statistics.Numeric.MeanKBN: calcMean")
--
-- Last example uses IO
--
-- >>> calcMean $ reduceSample @Mean []
-- *** Exception: EmptySample "Data.Monoid.Statistics.Numeric.MeanKBN: calcMean"
--
--
-- ==== Deriving instances
--
-- Type classes come in two variants, one that allow failure and one
-- for use in cases when quantity is always defined. This is not the
-- case for estimators, but true for distributions and intended for
-- such use cases. In that case 'CalcViaHas' could be used to derive
-- necessary instances.
--
-- >>> :{
-- data NormalDist = NormalDist !Double !Double
--   deriving (CalcMean,CalcVariance) via CalcViaHas NormalDist
-- instance HasMean NormalDist where
--   getMean (NormalDist mu _) = mu
-- instance HasVariance NormalDist where
--   getVariance   (NormalDist _ s) = s
--   getVarianceML (NormalDist _ s) = s
-- :}


-- | Value from which we can efficiently extract number of elements in
--   sample it represents.
class CalcCount a where
  -- | /Assumed O(1)/. Number of elements in sample.
  calcCount :: a -> Int

-- | Value from which we can efficiently calculate mean of sample or
--   distribution.
class CalcMean a where
  -- | /Assumed O(1)/ Returns @Nothing@ if there isn't enough data to
  --   make estimate or distribution doesn't have defined mean.
  --
  --   \[ \bar{x} = \frac{1}{N}\sum_{i=1}^N{x_i} \]
  calcMean :: MonadThrow m => a -> m Double

-- | Same as 'CalcMean' but should never fail
class CalcMean a => HasMean a where
  getMean :: a -> Double


-- | Values from which we can efficiently compute estimate of sample
--   variance or distribution variance. It has two methods: one which
--   applies bias correction to estimate and another that returns
--   maximul likelyhood estimate. For distribution they should return
--   same value.
class CalcVariance a where
  -- | /Assumed O(1)/ Calculate unbiased estimate of variance:
  --
  --   \[ \sigma^2 = \frac{1}{N-1}\sum_{i=1}^N(x_i - \bar{x})^2 \]
  calcVariance :: MonadThrow m => a -> m Double
  calcVariance = (Double -> Double) -> m Double -> m Double
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\Double
x->Double
xDouble -> Double -> Double
forall a. Num a => a -> a -> a
*Double
x) (m Double -> m Double) -> (a -> m Double) -> a -> m Double
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> m Double
forall a (m :: * -> *).
(CalcVariance a, MonadThrow m) =>
a -> m Double
calcStddev
  -- | /Assumed O(1)/ Calculate maximum likelihood estimate of variance:
  --
  --   \[ \sigma^2 = \frac{1}{N}\sum_{i=1}^N(x_i - \bar{x})^2 \]
  calcVarianceML :: MonadThrow m => a -> m Double
  calcVarianceML = (Double -> Double) -> m Double -> m Double
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\Double
x->Double
xDouble -> Double -> Double
forall a. Num a => a -> a -> a
*Double
x) (m Double -> m Double) -> (a -> m Double) -> a -> m Double
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> m Double
forall a (m :: * -> *).
(CalcVariance a, MonadThrow m) =>
a -> m Double
calcStddevML
  -- | Calculate sample standard deviation from unbiased estimation of
  --   variance.
  calcStddev :: MonadThrow m => a -> m Double
  calcStddev = (Double -> Double) -> m Double -> m Double
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Double -> Double
forall a. Floating a => a -> a
sqrt (m Double -> m Double) -> (a -> m Double) -> a -> m Double
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> m Double
forall a (m :: * -> *).
(CalcVariance a, MonadThrow m) =>
a -> m Double
calcVariance
  -- | Calculate sample standard deviation from maximum likelihood
  --   estimation of variance.
  calcStddevML :: (MonadThrow m) => a -> m Double
  calcStddevML = (Double -> Double) -> m Double -> m Double
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Double -> Double
forall a. Floating a => a -> a
sqrt (m Double -> m Double) -> (a -> m Double) -> a -> m Double
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> m Double
forall a (m :: * -> *).
(CalcVariance a, MonadThrow m) =>
a -> m Double
calcVarianceML
  {-# MINIMAL (calcVariance,calcVarianceML) | (calcStddev,calcStddevML) #-}

-- | Same as 'CalcVariance' but never fails
class CalcVariance a => HasVariance a where
  getVariance   :: a -> Double
  getVariance   = (\Double
x -> Double
xDouble -> Double -> Double
forall a. Num a => a -> a -> a
*Double
x) (Double -> Double) -> (a -> Double) -> a -> Double
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Double
forall a. HasVariance a => a -> Double
getStddev
  getVarianceML :: a -> Double
  getVarianceML = (\Double
x -> Double
xDouble -> Double -> Double
forall a. Num a => a -> a -> a
*Double
x) (Double -> Double) -> (a -> Double) -> a -> Double
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Double
forall a. HasVariance a => a -> Double
getStddevML
  getStddev     :: a -> Double
  getStddev     = Double -> Double
forall a. Floating a => a -> a
sqrt (Double -> Double) -> (a -> Double) -> a -> Double
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Double
forall a. HasVariance a => a -> Double
getVariance
  getStddevML   :: a -> Double
  getStddevML   = Double -> Double
forall a. Floating a => a -> a
sqrt (Double -> Double) -> (a -> Double) -> a -> Double
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Double
forall a. HasVariance a => a -> Double
getVarianceML
  {-# MINIMAL (getVariance,getVarianceML) | (getStddev,getStddevML) #-}




newtype CalcViaHas a = CalcViaHas a
  deriving newtype (CalcMean (CalcViaHas a)
CalcViaHas a -> Double
CalcMean (CalcViaHas a)
-> (CalcViaHas a -> Double) -> HasMean (CalcViaHas a)
forall a. HasMean a => CalcMean (CalcViaHas a)
forall a. HasMean a => CalcViaHas a -> Double
forall a. CalcMean a -> (a -> Double) -> HasMean a
getMean :: CalcViaHas a -> Double
$cgetMean :: forall a. HasMean a => CalcViaHas a -> Double
$cp1HasMean :: forall a. HasMean a => CalcMean (CalcViaHas a)
HasMean, CalcVariance (CalcViaHas a)
CalcViaHas a -> Double
CalcVariance (CalcViaHas a)
-> (CalcViaHas a -> Double)
-> (CalcViaHas a -> Double)
-> (CalcViaHas a -> Double)
-> (CalcViaHas a -> Double)
-> HasVariance (CalcViaHas a)
forall a. HasVariance a => CalcVariance (CalcViaHas a)
forall a. HasVariance a => CalcViaHas a -> Double
forall a.
CalcVariance a
-> (a -> Double)
-> (a -> Double)
-> (a -> Double)
-> (a -> Double)
-> HasVariance a
getStddevML :: CalcViaHas a -> Double
$cgetStddevML :: forall a. HasVariance a => CalcViaHas a -> Double
getStddev :: CalcViaHas a -> Double
$cgetStddev :: forall a. HasVariance a => CalcViaHas a -> Double
getVarianceML :: CalcViaHas a -> Double
$cgetVarianceML :: forall a. HasVariance a => CalcViaHas a -> Double
getVariance :: CalcViaHas a -> Double
$cgetVariance :: forall a. HasVariance a => CalcViaHas a -> Double
$cp1HasVariance :: forall a. HasVariance a => CalcVariance (CalcViaHas a)
HasVariance)

instance HasMean a => CalcMean (CalcViaHas a) where
  calcMean :: CalcViaHas a -> m Double
calcMean = Double -> m Double
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Double -> m Double)
-> (CalcViaHas a -> Double) -> CalcViaHas a -> m Double
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CalcViaHas a -> Double
forall a. HasMean a => a -> Double
getMean

instance HasVariance a => CalcVariance (CalcViaHas a) where
  calcVariance :: CalcViaHas a -> m Double
calcVariance   = Double -> m Double
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Double -> m Double)
-> (CalcViaHas a -> Double) -> CalcViaHas a -> m Double
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CalcViaHas a -> Double
forall a. HasVariance a => a -> Double
getVariance
  calcVarianceML :: CalcViaHas a -> m Double
calcVarianceML = Double -> m Double
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Double -> m Double)
-> (CalcViaHas a -> Double) -> CalcViaHas a -> m Double
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CalcViaHas a -> Double
forall a. HasVariance a => a -> Double
getVarianceML

----------------------------------------------------------------
-- Exceptions
----------------------------------------------------------------

-- | Identity monad which is used to encode partial functions for
--   'MonadThrow' based error handling. Its @MonadThrow@ instance
--   just throws normal exception.
newtype Partial a = Partial a
  deriving (Int -> Partial a -> ShowS
[Partial a] -> ShowS
Partial a -> String
(Int -> Partial a -> ShowS)
-> (Partial a -> String)
-> ([Partial a] -> ShowS)
-> Show (Partial a)
forall a. Show a => Int -> Partial a -> ShowS
forall a. Show a => [Partial a] -> ShowS
forall a. Show a => Partial a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Partial a] -> ShowS
$cshowList :: forall a. Show a => [Partial a] -> ShowS
show :: Partial a -> String
$cshow :: forall a. Show a => Partial a -> String
showsPrec :: Int -> Partial a -> ShowS
$cshowsPrec :: forall a. Show a => Int -> Partial a -> ShowS
Show, ReadPrec [Partial a]
ReadPrec (Partial a)
Int -> ReadS (Partial a)
ReadS [Partial a]
(Int -> ReadS (Partial a))
-> ReadS [Partial a]
-> ReadPrec (Partial a)
-> ReadPrec [Partial a]
-> Read (Partial a)
forall a. Read a => ReadPrec [Partial a]
forall a. Read a => ReadPrec (Partial a)
forall a. Read a => Int -> ReadS (Partial a)
forall a. Read a => ReadS [Partial a]
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [Partial a]
$creadListPrec :: forall a. Read a => ReadPrec [Partial a]
readPrec :: ReadPrec (Partial a)
$creadPrec :: forall a. Read a => ReadPrec (Partial a)
readList :: ReadS [Partial a]
$creadList :: forall a. Read a => ReadS [Partial a]
readsPrec :: Int -> ReadS (Partial a)
$creadsPrec :: forall a. Read a => Int -> ReadS (Partial a)
Read, Partial a -> Partial a -> Bool
(Partial a -> Partial a -> Bool)
-> (Partial a -> Partial a -> Bool) -> Eq (Partial a)
forall a. Eq a => Partial a -> Partial a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Partial a -> Partial a -> Bool
$c/= :: forall a. Eq a => Partial a -> Partial a -> Bool
== :: Partial a -> Partial a -> Bool
$c== :: forall a. Eq a => Partial a -> Partial a -> Bool
Eq, Eq (Partial a)
Eq (Partial a)
-> (Partial a -> Partial a -> Ordering)
-> (Partial a -> Partial a -> Bool)
-> (Partial a -> Partial a -> Bool)
-> (Partial a -> Partial a -> Bool)
-> (Partial a -> Partial a -> Bool)
-> (Partial a -> Partial a -> Partial a)
-> (Partial a -> Partial a -> Partial a)
-> Ord (Partial a)
Partial a -> Partial a -> Bool
Partial a -> Partial a -> Ordering
Partial a -> Partial a -> Partial a
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall a. Ord a => Eq (Partial a)
forall a. Ord a => Partial a -> Partial a -> Bool
forall a. Ord a => Partial a -> Partial a -> Ordering
forall a. Ord a => Partial a -> Partial a -> Partial a
min :: Partial a -> Partial a -> Partial a
$cmin :: forall a. Ord a => Partial a -> Partial a -> Partial a
max :: Partial a -> Partial a -> Partial a
$cmax :: forall a. Ord a => Partial a -> Partial a -> Partial a
>= :: Partial a -> Partial a -> Bool
$c>= :: forall a. Ord a => Partial a -> Partial a -> Bool
> :: Partial a -> Partial a -> Bool
$c> :: forall a. Ord a => Partial a -> Partial a -> Bool
<= :: Partial a -> Partial a -> Bool
$c<= :: forall a. Ord a => Partial a -> Partial a -> Bool
< :: Partial a -> Partial a -> Bool
$c< :: forall a. Ord a => Partial a -> Partial a -> Bool
compare :: Partial a -> Partial a -> Ordering
$ccompare :: forall a. Ord a => Partial a -> Partial a -> Ordering
$cp1Ord :: forall a. Ord a => Eq (Partial a)
Ord, Typeable, Typeable (Partial a)
DataType
Constr
Typeable (Partial a)
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> Partial a -> c (Partial a))
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c (Partial a))
-> (Partial a -> Constr)
-> (Partial a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c (Partial a)))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c (Partial a)))
-> ((forall b. Data b => b -> b) -> Partial a -> Partial a)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> Partial a -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> Partial a -> r)
-> (forall u. (forall d. Data d => d -> u) -> Partial a -> [u])
-> (forall u.
    Int -> (forall d. Data d => d -> u) -> Partial a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> Partial a -> m (Partial a))
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Partial a -> m (Partial a))
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Partial a -> m (Partial a))
-> Data (Partial a)
Partial a -> DataType
Partial a -> Constr
(forall d. Data d => c (t d)) -> Maybe (c (Partial a))
(forall b. Data b => b -> b) -> Partial a -> Partial a
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Partial a -> c (Partial a)
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (Partial a)
forall a. Data a => Typeable (Partial a)
forall a. Data a => Partial a -> DataType
forall a. Data a => Partial a -> Constr
forall a.
Data a =>
(forall b. Data b => b -> b) -> Partial a -> Partial a
forall a u.
Data a =>
Int -> (forall d. Data d => d -> u) -> Partial a -> u
forall a u.
Data a =>
(forall d. Data d => d -> u) -> Partial a -> [u]
forall a r r'.
Data a =>
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Partial a -> r
forall a r r'.
Data a =>
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Partial a -> r
forall a (m :: * -> *).
(Data a, Monad m) =>
(forall d. Data d => d -> m d) -> Partial a -> m (Partial a)
forall a (m :: * -> *).
(Data a, MonadPlus m) =>
(forall d. Data d => d -> m d) -> Partial a -> m (Partial a)
forall a (c :: * -> *).
Data a =>
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (Partial a)
forall a (c :: * -> *).
Data a =>
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Partial a -> c (Partial a)
forall a (t :: * -> *) (c :: * -> *).
(Data a, Typeable t) =>
(forall d. Data d => c (t d)) -> Maybe (c (Partial a))
forall a (t :: * -> * -> *) (c :: * -> *).
(Data a, Typeable t) =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c (Partial a))
forall a.
Typeable a
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> Partial a -> u
forall u. (forall d. Data d => d -> u) -> Partial a -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Partial a -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Partial a -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Partial a -> m (Partial a)
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Partial a -> m (Partial a)
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (Partial a)
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Partial a -> c (Partial a)
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c (Partial a))
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c (Partial a))
$cPartial :: Constr
$tPartial :: DataType
gmapMo :: (forall d. Data d => d -> m d) -> Partial a -> m (Partial a)
$cgmapMo :: forall a (m :: * -> *).
(Data a, MonadPlus m) =>
(forall d. Data d => d -> m d) -> Partial a -> m (Partial a)
gmapMp :: (forall d. Data d => d -> m d) -> Partial a -> m (Partial a)
$cgmapMp :: forall a (m :: * -> *).
(Data a, MonadPlus m) =>
(forall d. Data d => d -> m d) -> Partial a -> m (Partial a)
gmapM :: (forall d. Data d => d -> m d) -> Partial a -> m (Partial a)
$cgmapM :: forall a (m :: * -> *).
(Data a, Monad m) =>
(forall d. Data d => d -> m d) -> Partial a -> m (Partial a)
gmapQi :: Int -> (forall d. Data d => d -> u) -> Partial a -> u
$cgmapQi :: forall a u.
Data a =>
Int -> (forall d. Data d => d -> u) -> Partial a -> u
gmapQ :: (forall d. Data d => d -> u) -> Partial a -> [u]
$cgmapQ :: forall a u.
Data a =>
(forall d. Data d => d -> u) -> Partial a -> [u]
gmapQr :: (r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Partial a -> r
$cgmapQr :: forall a r r'.
Data a =>
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Partial a -> r
gmapQl :: (r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Partial a -> r
$cgmapQl :: forall a r r'.
Data a =>
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Partial a -> r
gmapT :: (forall b. Data b => b -> b) -> Partial a -> Partial a
$cgmapT :: forall a.
Data a =>
(forall b. Data b => b -> b) -> Partial a -> Partial a
dataCast2 :: (forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c (Partial a))
$cdataCast2 :: forall a (t :: * -> * -> *) (c :: * -> *).
(Data a, Typeable t) =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c (Partial a))
dataCast1 :: (forall d. Data d => c (t d)) -> Maybe (c (Partial a))
$cdataCast1 :: forall a (t :: * -> *) (c :: * -> *).
(Data a, Typeable t) =>
(forall d. Data d => c (t d)) -> Maybe (c (Partial a))
dataTypeOf :: Partial a -> DataType
$cdataTypeOf :: forall a. Data a => Partial a -> DataType
toConstr :: Partial a -> Constr
$ctoConstr :: forall a. Data a => Partial a -> Constr
gunfold :: (forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (Partial a)
$cgunfold :: forall a (c :: * -> *).
Data a =>
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (Partial a)
gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Partial a -> c (Partial a)
$cgfoldl :: forall a (c :: * -> *).
Data a =>
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Partial a -> c (Partial a)
$cp1Data :: forall a. Data a => Typeable (Partial a)
Data, (forall x. Partial a -> Rep (Partial a) x)
-> (forall x. Rep (Partial a) x -> Partial a)
-> Generic (Partial a)
forall x. Rep (Partial a) x -> Partial a
forall x. Partial a -> Rep (Partial a) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall a x. Rep (Partial a) x -> Partial a
forall a x. Partial a -> Rep (Partial a) x
$cto :: forall a x. Rep (Partial a) x -> Partial a
$cfrom :: forall a x. Partial a -> Rep (Partial a) x
Generic)

-- | Convert error to IO exception. This way one could for example
--   convert case when some statistics is not defined to an exception:
--
-- >>> calcMean $ reduceSample @Mean []
-- *** Exception: EmptySample "Data.Monoid.Statistics.Numeric.MeanKBN: calcMean"
partial :: HasCallStack => Partial a -> a
partial :: Partial a -> a
partial (Partial a
x) = a
x

instance Functor Partial where
  fmap :: (a -> b) -> Partial a -> Partial b
fmap a -> b
f (Partial a
a) = b -> Partial b
forall a. a -> Partial a
Partial (a -> b
f a
a)

instance Applicative Partial where
  pure :: a -> Partial a
pure = a -> Partial a
forall a. a -> Partial a
Partial
  Partial a -> b
f <*> :: Partial (a -> b) -> Partial a -> Partial b
<*> Partial a
a = b -> Partial b
forall a. a -> Partial a
Partial (a -> b
f a
a)
  (!Partial a
_) *> :: Partial a -> Partial b -> Partial b
*> Partial b
a   = Partial b
a
  Partial a
a   <* :: Partial a -> Partial b -> Partial a
<* (!Partial b
_) = Partial a
a
instance Monad Partial where
  return :: a -> Partial a
return = a -> Partial a
forall (f :: * -> *) a. Applicative f => a -> f a
pure
  Partial a
a >>= :: Partial a -> (a -> Partial b) -> Partial b
>>= a -> Partial b
f = a -> Partial b
f a
a
  >> :: Partial a -> Partial b -> Partial b
(>>) = Partial a -> Partial b -> Partial b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
(*>)

instance MonadThrow Partial where
  throwM :: e -> Partial a
throwM = e -> Partial a
forall a e. Exception e => e -> a
throw

-- | Exception which is thrown when we can't compute some value
data SampleError
  = EmptySample String
  -- ^ @EmptySample function@: We're trying to compute quantity that
  --   is undefined for empty sample.
  | InvalidSample String String
  -- ^ @InvalidSample function descripton@ quantity in question could
  --   not be computed for some other reason
  deriving Int -> SampleError -> ShowS
[SampleError] -> ShowS
SampleError -> String
(Int -> SampleError -> ShowS)
-> (SampleError -> String)
-> ([SampleError] -> ShowS)
-> Show SampleError
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [SampleError] -> ShowS
$cshowList :: [SampleError] -> ShowS
show :: SampleError -> String
$cshow :: SampleError -> String
showsPrec :: Int -> SampleError -> ShowS
$cshowsPrec :: Int -> SampleError -> ShowS
Show

instance Exception SampleError


----------------------------------------------------------------
-- Generic monoids
----------------------------------------------------------------

-- | Strict pair. It allows to calculate two statistics in parallel
data Pair a b = Pair !a !b
              deriving (Int -> Pair a b -> ShowS
[Pair a b] -> ShowS
Pair a b -> String
(Int -> Pair a b -> ShowS)
-> (Pair a b -> String) -> ([Pair a b] -> ShowS) -> Show (Pair a b)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall a b. (Show a, Show b) => Int -> Pair a b -> ShowS
forall a b. (Show a, Show b) => [Pair a b] -> ShowS
forall a b. (Show a, Show b) => Pair a b -> String
showList :: [Pair a b] -> ShowS
$cshowList :: forall a b. (Show a, Show b) => [Pair a b] -> ShowS
show :: Pair a b -> String
$cshow :: forall a b. (Show a, Show b) => Pair a b -> String
showsPrec :: Int -> Pair a b -> ShowS
$cshowsPrec :: forall a b. (Show a, Show b) => Int -> Pair a b -> ShowS
Show,Pair a b -> Pair a b -> Bool
(Pair a b -> Pair a b -> Bool)
-> (Pair a b -> Pair a b -> Bool) -> Eq (Pair a b)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall a b. (Eq a, Eq b) => Pair a b -> Pair a b -> Bool
/= :: Pair a b -> Pair a b -> Bool
$c/= :: forall a b. (Eq a, Eq b) => Pair a b -> Pair a b -> Bool
== :: Pair a b -> Pair a b -> Bool
$c== :: forall a b. (Eq a, Eq b) => Pair a b -> Pair a b -> Bool
Eq,Eq (Pair a b)
Eq (Pair a b)
-> (Pair a b -> Pair a b -> Ordering)
-> (Pair a b -> Pair a b -> Bool)
-> (Pair a b -> Pair a b -> Bool)
-> (Pair a b -> Pair a b -> Bool)
-> (Pair a b -> Pair a b -> Bool)
-> (Pair a b -> Pair a b -> Pair a b)
-> (Pair a b -> Pair a b -> Pair a b)
-> Ord (Pair a b)
Pair a b -> Pair a b -> Bool
Pair a b -> Pair a b -> Ordering
Pair a b -> Pair a b -> Pair a b
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall a b. (Ord a, Ord b) => Eq (Pair a b)
forall a b. (Ord a, Ord b) => Pair a b -> Pair a b -> Bool
forall a b. (Ord a, Ord b) => Pair a b -> Pair a b -> Ordering
forall a b. (Ord a, Ord b) => Pair a b -> Pair a b -> Pair a b
min :: Pair a b -> Pair a b -> Pair a b
$cmin :: forall a b. (Ord a, Ord b) => Pair a b -> Pair a b -> Pair a b
max :: Pair a b -> Pair a b -> Pair a b
$cmax :: forall a b. (Ord a, Ord b) => Pair a b -> Pair a b -> Pair a b
>= :: Pair a b -> Pair a b -> Bool
$c>= :: forall a b. (Ord a, Ord b) => Pair a b -> Pair a b -> Bool
> :: Pair a b -> Pair a b -> Bool
$c> :: forall a b. (Ord a, Ord b) => Pair a b -> Pair a b -> Bool
<= :: Pair a b -> Pair a b -> Bool
$c<= :: forall a b. (Ord a, Ord b) => Pair a b -> Pair a b -> Bool
< :: Pair a b -> Pair a b -> Bool
$c< :: forall a b. (Ord a, Ord b) => Pair a b -> Pair a b -> Bool
compare :: Pair a b -> Pair a b -> Ordering
$ccompare :: forall a b. (Ord a, Ord b) => Pair a b -> Pair a b -> Ordering
$cp1Ord :: forall a b. (Ord a, Ord b) => Eq (Pair a b)
Ord,Typeable,Typeable (Pair a b)
DataType
Constr
Typeable (Pair a b)
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> Pair a b -> c (Pair a b))
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c (Pair a b))
-> (Pair a b -> Constr)
-> (Pair a b -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c (Pair a b)))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c (Pair a b)))
-> ((forall b. Data b => b -> b) -> Pair a b -> Pair a b)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> Pair a b -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> Pair a b -> r)
-> (forall u. (forall d. Data d => d -> u) -> Pair a b -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> Pair a b -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> Pair a b -> m (Pair a b))
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Pair a b -> m (Pair a b))
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Pair a b -> m (Pair a b))
-> Data (Pair a b)
Pair a b -> DataType
Pair a b -> Constr
(forall b. Data b => b -> b) -> Pair a b -> Pair a b
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Pair a b -> c (Pair a b)
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (Pair a b)
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c (Pair a b))
forall a.
Typeable a
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> Pair a b -> u
forall u. (forall d. Data d => d -> u) -> Pair a b -> [u]
forall a b. (Data a, Data b) => Typeable (Pair a b)
forall a b. (Data a, Data b) => Pair a b -> DataType
forall a b. (Data a, Data b) => Pair a b -> Constr
forall a b.
(Data a, Data b) =>
(forall b. Data b => b -> b) -> Pair a b -> Pair a b
forall a b u.
(Data a, Data b) =>
Int -> (forall d. Data d => d -> u) -> Pair a b -> u
forall a b u.
(Data a, Data b) =>
(forall d. Data d => d -> u) -> Pair a b -> [u]
forall a b r r'.
(Data a, Data b) =>
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Pair a b -> r
forall a b r r'.
(Data a, Data b) =>
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Pair a b -> r
forall a b (m :: * -> *).
(Data a, Data b, Monad m) =>
(forall d. Data d => d -> m d) -> Pair a b -> m (Pair a b)
forall a b (m :: * -> *).
(Data a, Data b, MonadPlus m) =>
(forall d. Data d => d -> m d) -> Pair a b -> m (Pair a b)
forall a b (c :: * -> *).
(Data a, Data b) =>
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (Pair a b)
forall a b (c :: * -> *).
(Data a, Data b) =>
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Pair a b -> c (Pair a b)
forall a b (t :: * -> *) (c :: * -> *).
(Data a, Data b, Typeable t) =>
(forall d. Data d => c (t d)) -> Maybe (c (Pair a b))
forall a b (t :: * -> * -> *) (c :: * -> *).
(Data a, Data b, Typeable t) =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c (Pair a b))
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Pair a b -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Pair a b -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Pair a b -> m (Pair a b)
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Pair a b -> m (Pair a b)
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (Pair a b)
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Pair a b -> c (Pair a b)
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c (Pair a b))
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c (Pair a b))
$cPair :: Constr
$tPair :: DataType
gmapMo :: (forall d. Data d => d -> m d) -> Pair a b -> m (Pair a b)
$cgmapMo :: forall a b (m :: * -> *).
(Data a, Data b, MonadPlus m) =>
(forall d. Data d => d -> m d) -> Pair a b -> m (Pair a b)
gmapMp :: (forall d. Data d => d -> m d) -> Pair a b -> m (Pair a b)
$cgmapMp :: forall a b (m :: * -> *).
(Data a, Data b, MonadPlus m) =>
(forall d. Data d => d -> m d) -> Pair a b -> m (Pair a b)
gmapM :: (forall d. Data d => d -> m d) -> Pair a b -> m (Pair a b)
$cgmapM :: forall a b (m :: * -> *).
(Data a, Data b, Monad m) =>
(forall d. Data d => d -> m d) -> Pair a b -> m (Pair a b)
gmapQi :: Int -> (forall d. Data d => d -> u) -> Pair a b -> u
$cgmapQi :: forall a b u.
(Data a, Data b) =>
Int -> (forall d. Data d => d -> u) -> Pair a b -> u
gmapQ :: (forall d. Data d => d -> u) -> Pair a b -> [u]
$cgmapQ :: forall a b u.
(Data a, Data b) =>
(forall d. Data d => d -> u) -> Pair a b -> [u]
gmapQr :: (r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Pair a b -> r
$cgmapQr :: forall a b r r'.
(Data a, Data b) =>
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Pair a b -> r
gmapQl :: (r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Pair a b -> r
$cgmapQl :: forall a b r r'.
(Data a, Data b) =>
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Pair a b -> r
gmapT :: (forall b. Data b => b -> b) -> Pair a b -> Pair a b
$cgmapT :: forall a b.
(Data a, Data b) =>
(forall b. Data b => b -> b) -> Pair a b -> Pair a b
dataCast2 :: (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c (Pair a b))
$cdataCast2 :: forall a b (t :: * -> * -> *) (c :: * -> *).
(Data a, Data b, Typeable t) =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c (Pair a b))
dataCast1 :: (forall d. Data d => c (t d)) -> Maybe (c (Pair a b))
$cdataCast1 :: forall a b (t :: * -> *) (c :: * -> *).
(Data a, Data b, Typeable t) =>
(forall d. Data d => c (t d)) -> Maybe (c (Pair a b))
dataTypeOf :: Pair a b -> DataType
$cdataTypeOf :: forall a b. (Data a, Data b) => Pair a b -> DataType
toConstr :: Pair a b -> Constr
$ctoConstr :: forall a b. (Data a, Data b) => Pair a b -> Constr
gunfold :: (forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (Pair a b)
$cgunfold :: forall a b (c :: * -> *).
(Data a, Data b) =>
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (Pair a b)
gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Pair a b -> c (Pair a b)
$cgfoldl :: forall a b (c :: * -> *).
(Data a, Data b) =>
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Pair a b -> c (Pair a b)
$cp1Data :: forall a b. (Data a, Data b) => Typeable (Pair a b)
Data,(forall x. Pair a b -> Rep (Pair a b) x)
-> (forall x. Rep (Pair a b) x -> Pair a b) -> Generic (Pair a b)
forall x. Rep (Pair a b) x -> Pair a b
forall x. Pair a b -> Rep (Pair a b) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall a b x. Rep (Pair a b) x -> Pair a b
forall a b x. Pair a b -> Rep (Pair a b) x
$cto :: forall a b x. Rep (Pair a b) x -> Pair a b
$cfrom :: forall a b x. Pair a b -> Rep (Pair a b) x
Generic)

instance (Semigroup a, Semigroup b) => Semigroup (Pair a b) where
  Pair a
x b
y <> :: Pair a b -> Pair a b -> Pair a b
<> Pair a
x' b
y' = a -> b -> Pair a b
forall a b. a -> b -> Pair a b
Pair (a
x a -> a -> a
forall a. Semigroup a => a -> a -> a
<> a
x') (b
y b -> b -> b
forall a. Semigroup a => a -> a -> a
<> b
y')
  {-# INLINABLE (<>) #-}

instance (Monoid a, Monoid b) => Monoid (Pair a b) where
  mempty :: Pair a b
mempty  = a -> b -> Pair a b
forall a b. a -> b -> Pair a b
Pair a
forall a. Monoid a => a
mempty b
forall a. Monoid a => a
mempty
  mappend :: Pair a b -> Pair a b -> Pair a b
mappend = Pair a b -> Pair a b -> Pair a b
forall a. Semigroup a => a -> a -> a
(<>)
  {-# INLINABLE mempty  #-}
  {-# INLINABLE mappend #-}

instance (StatMonoid a x, StatMonoid b x) => StatMonoid (Pair a b) x where
  addValue :: Pair a b -> x -> Pair a b
addValue (Pair a
a b
b) !x
x = a -> b -> Pair a b
forall a b. a -> b -> Pair a b
Pair (a -> x -> a
forall m a. StatMonoid m a => m -> a -> m
addValue a
a x
x) (b -> x -> b
forall m a. StatMonoid m a => m -> a -> m
addValue b
b x
x)
  singletonMonoid :: x -> Pair a b
singletonMonoid x
x = a -> b -> Pair a b
forall a b. a -> b -> Pair a b
Pair (x -> a
forall m a. StatMonoid m a => a -> m
singletonMonoid x
x) (x -> b
forall m a. StatMonoid m a => a -> m
singletonMonoid x
x)
  {-# INLINE addValue        #-}
  {-# INLINE singletonMonoid #-}


-- | Strict pair for parallel accumulation
data PPair a b = PPair !a !b

instance (Semigroup a, Semigroup b) => Semigroup (PPair a b) where
  PPair a
x b
y <> :: PPair a b -> PPair a b -> PPair a b
<> PPair a
x' b
y' = a -> b -> PPair a b
forall a b. a -> b -> PPair a b
PPair (a
x a -> a -> a
forall a. Semigroup a => a -> a -> a
<> a
x') (b
y b -> b -> b
forall a. Semigroup a => a -> a -> a
<> b
y')
  {-# INLINABLE (<>) #-}

instance (Monoid a, Monoid b) => Monoid (PPair a b) where
  mempty :: PPair a b
mempty  = a -> b -> PPair a b
forall a b. a -> b -> PPair a b
PPair a
forall a. Monoid a => a
mempty b
forall a. Monoid a => a
mempty
  mappend :: PPair a b -> PPair a b -> PPair a b
mappend = PPair a b -> PPair a b -> PPair a b
forall a. Semigroup a => a -> a -> a
(<>)
  {-# INLINABLE mempty  #-}
  {-# INLINABLE mappend #-}

instance (StatMonoid a x, StatMonoid b y) => StatMonoid (PPair a b) (x,y) where
  addValue :: PPair a b -> (x, y) -> PPair a b
addValue (PPair a
a b
b) (!x
x,!y
y) = a -> b -> PPair a b
forall a b. a -> b -> PPair a b
PPair (a -> x -> a
forall m a. StatMonoid m a => m -> a -> m
addValue a
a x
x) (b -> y -> b
forall m a. StatMonoid m a => m -> a -> m
addValue b
b y
y)
  singletonMonoid :: (x, y) -> PPair a b
singletonMonoid (!x
x,!y
y) = a -> b -> PPair a b
forall a b. a -> b -> PPair a b
PPair (x -> a
forall m a. StatMonoid m a => a -> m
singletonMonoid x
x) (y -> b
forall m a. StatMonoid m a => a -> m
singletonMonoid y
y)
  {-# INLINE addValue        #-}
  {-# INLINE singletonMonoid #-}





derivingUnbox "Pair"
  [t| forall a b. (Unbox a, Unbox b) => Pair a b -> (a,b) |]
  [| \(Pair a b) -> (a,b) |]
  [| \(a,b) -> Pair a b   |]

-- $setup
--
-- >>> :set -XDerivingVia
-- >>> import Data.Monoid.Statistics.Numeric