{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances #-} -- | -- Module : Data.Metrics.Counter -- Copyright : (c) Ian Duncan 2013 -- Stability : experimental -- Portability : non-portable -- -- An incrementing and decrementing counter metric -- -- > import Data.Metrics.Counter -- > -- > main :: IO () -- > main = do -- > c <- counter -- > increment c -- > x <- value c -- > print $ x == 1 -- module Data.Metrics.Counter ( Counter, counter, increment, increment', decrement, decrement', module Data.Metrics.Types ) where import Control.Monad.Primitive import qualified Data.HashMap.Strict as H import Data.Metrics.Internal import Data.Metrics.Types import Data.Primitive.MutVar -- | A basic atomic counter. newtype Counter m = Counter { fromCounter :: MV m Int } instance PrimMonad m => Count m (Counter m) where count (Counter ref) = readMutVar ref instance PrimMonad m => Value m (Counter m) Int where value (Counter ref) = readMutVar ref instance PrimMonad m => Set m (Counter m) Int where set (Counter ref) x = updateRef ref (const x) instance PrimMonad m => Clear m (Counter m) where clear c = set c 0 -- | Create a new counter. counter :: (Functor m, PrimMonad m) => m (Counter m) counter = fmap Counter $ newMutVar 0 -- | Bump up a counter by 1. increment :: PrimMonad m => Counter m -> m () increment = flip increment' 1 -- | Add an arbitrary amount to a counter. increment' :: PrimMonad m => Counter m -> Int -> m () increment' (Counter ref) x = updateRef ref (+ x) -- | Decrease the value of a counter by 1. decrement :: PrimMonad m => Counter m -> m () decrement = flip decrement' 1 -- | Subtract an arbitrary amount from a counter. decrement' :: PrimMonad m => Counter m -> Int -> m () decrement' (Counter ref) x = updateRef ref (subtract x)