{-# LANGUAGE NamedFieldPuns #-}
module CRDT.Cv.PNCounter
( PNCounter (..)
, initial
, query
, decrement
, increment
) where
import Data.Semilattice (Semilattice)
import CRDT.Cv.GCounter (GCounter)
import qualified CRDT.Cv.GCounter as GCounter
data PNCounter a = PNCounter
{ PNCounter a -> GCounter a
positive :: !(GCounter a)
, PNCounter a -> GCounter a
negative :: !(GCounter a)
}
deriving (PNCounter a -> PNCounter a -> Bool
(PNCounter a -> PNCounter a -> Bool)
-> (PNCounter a -> PNCounter a -> Bool) -> Eq (PNCounter a)
forall a. Eq a => PNCounter a -> PNCounter a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: PNCounter a -> PNCounter a -> Bool
$c/= :: forall a. Eq a => PNCounter a -> PNCounter a -> Bool
== :: PNCounter a -> PNCounter a -> Bool
$c== :: forall a. Eq a => PNCounter a -> PNCounter a -> Bool
Eq, Int -> PNCounter a -> ShowS
[PNCounter a] -> ShowS
PNCounter a -> String
(Int -> PNCounter a -> ShowS)
-> (PNCounter a -> String)
-> ([PNCounter a] -> ShowS)
-> Show (PNCounter a)
forall a. Show a => Int -> PNCounter a -> ShowS
forall a. Show a => [PNCounter a] -> ShowS
forall a. Show a => PNCounter a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [PNCounter a] -> ShowS
$cshowList :: forall a. Show a => [PNCounter a] -> ShowS
show :: PNCounter a -> String
$cshow :: forall a. Show a => PNCounter a -> String
showsPrec :: Int -> PNCounter a -> ShowS
$cshowsPrec :: forall a. Show a => Int -> PNCounter a -> ShowS
Show)
instance Ord a => Semigroup (PNCounter a) where
PNCounter GCounter a
p1 GCounter a
n1 <> :: PNCounter a -> PNCounter a -> PNCounter a
<> PNCounter GCounter a
p2 GCounter a
n2 = GCounter a -> GCounter a -> PNCounter a
forall a. GCounter a -> GCounter a -> PNCounter a
PNCounter (GCounter a
p1 GCounter a -> GCounter a -> GCounter a
forall a. Semigroup a => a -> a -> a
<> GCounter a
p2) (GCounter a
n1 GCounter a -> GCounter a -> GCounter a
forall a. Semigroup a => a -> a -> a
<> GCounter a
n2)
instance Ord a => Semilattice (PNCounter a)
query :: Num a => PNCounter a -> a
query :: PNCounter a -> a
query PNCounter{GCounter a
positive :: GCounter a
positive :: forall a. PNCounter a -> GCounter a
positive, GCounter a
negative :: GCounter a
negative :: forall a. PNCounter a -> GCounter a
negative} =
GCounter a -> a
forall a. Num a => GCounter a -> a
GCounter.query GCounter a
positive a -> a -> a
forall a. Num a => a -> a -> a
- GCounter a -> a
forall a. Num a => GCounter a -> a
GCounter.query GCounter a
negative
decrement
:: Num a
=> Word
-> PNCounter a
-> PNCounter a
decrement :: Word -> PNCounter a -> PNCounter a
decrement Word
i pnc :: PNCounter a
pnc@PNCounter{GCounter a
negative :: GCounter a
negative :: forall a. PNCounter a -> GCounter a
negative} =
PNCounter a
pnc{negative :: GCounter a
negative = Word -> GCounter a -> GCounter a
forall a. Num a => Word -> GCounter a -> GCounter a
GCounter.increment Word
i GCounter a
negative}
increment
:: Num a
=> Word
-> PNCounter a
-> PNCounter a
increment :: Word -> PNCounter a -> PNCounter a
increment Word
i pnc :: PNCounter a
pnc@PNCounter{GCounter a
positive :: GCounter a
positive :: forall a. PNCounter a -> GCounter a
positive} =
PNCounter a
pnc{positive :: GCounter a
positive = Word -> GCounter a -> GCounter a
forall a. Num a => Word -> GCounter a -> GCounter a
GCounter.increment Word
i GCounter a
positive}
initial :: PNCounter a
initial :: PNCounter a
initial = PNCounter :: forall a. GCounter a -> GCounter a -> PNCounter a
PNCounter{positive :: GCounter a
positive = GCounter a
forall a. GCounter a
GCounter.initial, negative :: GCounter a
negative = GCounter a
forall a. GCounter a
GCounter.initial}