module CRDT.Cm.Counter
( Counter (..)
, CounterOp (..)
, initial
) where
import Algebra.PartialOrd (PartialOrd (..))
import Data.Observe (Observe (..))
import CRDT.Cm (CmRDT (..))
newtype Counter a = Counter a
deriving (Show)
data CounterOp a = Increment | Decrement
deriving (Bounded, Enum, Eq, Show)
instance (Num a, Eq a) => CmRDT (Counter a) (CounterOp a) (CounterOp a) where
updateAtSource = pure
updateDownstream = opToFunc
instance Observe (Counter a) where
type Observed (Counter a) = a
observe (Counter c) = c
instance PartialOrd (CounterOp a) where
leq _ _ = False
initial :: Num a => Counter a
initial = Counter 0
opToFunc :: Num a => CounterOp a -> Counter a -> Counter a
opToFunc op (Counter c) =
Counter $ case op of
Increment -> c + 1
Decrement -> c 1