module CRDT.Cv.TwoPSet ( TwoPSet (..) , add , initial , member , remove , singleton , isKnown ) where import Data.Map.Strict (Map) import qualified Data.Map.Strict as Map import Data.Maybe (fromMaybe) import Data.Semigroup (Semigroup ((<>))) import Data.Semilattice (Semilattice) newtype TwoPSet a = TwoPSet (Map a Bool) deriving (Eq, Show) instance Ord a => Semigroup (TwoPSet a) where TwoPSet m1 <> TwoPSet m2 = TwoPSet (Map.unionWith (&&) m1 m2) instance Ord a => Semilattice (TwoPSet a) add :: Ord a => a -> TwoPSet a -> TwoPSet a add e (TwoPSet m) = TwoPSet (Map.insertWith (&&) e True m) initial :: TwoPSet a initial = TwoPSet Map.empty member :: Ord a => a -> TwoPSet a -> Bool member e (TwoPSet m) = fromMaybe False $ Map.lookup e m remove :: Ord a => a -> TwoPSet a -> TwoPSet a remove e (TwoPSet m) = TwoPSet $ Map.adjust (const False) e m singleton :: Ord a => a -> TwoPSet a singleton a = add a initial -- | XXX Internal isKnown :: Ord a => a -> TwoPSet a -> Bool isKnown e (TwoPSet m) = Map.member e m