module CRDT.LWW
( LWW (..)
, initial
, assign
, query
, Assign (..)
) where
import Data.Function (on)
import Data.Semigroup (Semigroup, (<>))
import Data.Semilattice (Semilattice)
import CRDT.Cm (CausalOrd (..), CmRDT (..))
import LamportClock (Clock (newTimestamp), Timestamp)
data LWW a = LWW
{ value :: !a
, timestamp :: !Timestamp
}
deriving (Show)
instance Eq (LWW a) where
(==) = (==) `on` timestamp
instance Ord (LWW a) where
(<=) = (<=) `on` timestamp
instance Semigroup (LWW a) where
(<>) = max
instance Semilattice (LWW a)
initial :: Clock f => a -> f (LWW a)
initial value = LWW value <$> newTimestamp
assign :: Clock f => a -> LWW a -> f (LWW a)
assign value _ = LWW value <$> newTimestamp
query :: LWW a -> a
query = value
instance CausalOrd (LWW a) where
before _ _ = False
newtype Assign a = Assign a
deriving (Eq, Show)
instance Eq a => CmRDT (LWW a) where
type Op (LWW a) = Assign a
type Payload (LWW a) = LWW a
type View (LWW a) = a
updateAtSource (Assign value) = LWW value <$> newTimestamp
updateDownstream = (<>)
view = value