{-# LANGUAGE LambdaCase #-} {-# LANGUAGE TypeFamilies #-} -- | TODO(cblp, 2017-09-29) USet? module CRDT.Cm.TwoPSet ( TwoPSet (..) ) where import Data.Map.Strict (Map) import qualified Data.Map.Strict as Map import CRDT.Cm (CausalOrd (..), CmRDT (..)) data TwoPSet a = Add a | Remove a deriving (Eq, Show) instance Ord a => CmRDT (TwoPSet a) where type Payload (TwoPSet a) = Map a Bool initial = Map.empty makeOp op payload = case op of Add _ -> Just $ pure op Remove a | isKnown a -> Just $ pure op | otherwise -> Nothing where isKnown a = Map.member a payload apply = \case Add a -> Map.insertWith (&&) a True Remove a -> Map.insert a False instance Eq a => CausalOrd (TwoPSet a) where Add b `precedes` Remove a = a == b -- `Remove e` can occur only after `Add e` _ `precedes` _ = False -- Any other are not ordered