-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Conflict-free replicated data types -- -- Definitions of CmRDT and CvRDT. Implementations for some classic -- CRDTs. @package crdt @version 0.4 module Data.Semilattice -- | A semilattice. -- -- It may be a join-semilattice, or meet-semilattice, it doesn't matter. -- -- If it matters for you, use package lattices. -- -- In addition to Semigroup, Semilattice defines this laws: -- -- class Semigroup a => Semilattice a -- | Just (<>), specialized to Semilattice. slappend :: Semilattice a => a -> a -> a infixr 6 `slappend` module CRDT.Timestamp type Timestamp = Natural module CRDT.Cv -- | State-based, or convergent (Cv) replicated data type. -- -- Update is any function modifying state. -- -- Query function is not needed. State itself is exposed. In other words, -- query = id. -- -- Actually, a CvRDT is nothing more a Semilattice. type CvRDT = Semilattice module CRDT.GCounter.Cv.Internal -- | Grow-only counter. newtype GCounter a GCounter :: (IntMap a) -> GCounter a instance GHC.Show.Show a => GHC.Show.Show (CRDT.GCounter.Cv.Internal.GCounter a) instance GHC.Classes.Eq a => GHC.Classes.Eq (CRDT.GCounter.Cv.Internal.GCounter a) instance GHC.Classes.Ord a => Data.Semigroup.Semigroup (CRDT.GCounter.Cv.Internal.GCounter a) instance GHC.Classes.Ord a => Data.Semilattice.Semilattice (CRDT.GCounter.Cv.Internal.GCounter a) module CRDT.GCounter.Cv -- | Grow-only counter. data GCounter a -- | Initial state initial :: GCounter a -- | Get value from the state query :: Num a => GCounter a -> a -- | Increment counter increment :: Num a => Word -> GCounter a -> GCounter a module CRDT.GSet.Cv.Internal -- | Grow-only set type GSet = Set instance GHC.Classes.Ord a => Data.Semilattice.Semilattice (Data.Set.Base.Set a) module CRDT.GSet.Cv -- | update add :: Ord a => a -> GSet a -> GSet a -- | initialization initial :: GSet a query :: Ord a => a -> GSet a -> Bool module CRDT.PNCounter.Cv.Internal -- | Positive-negative counter. Allows incrementing and decrementing. Nice -- example of combining of existing CvRDT (GCounter in this case) -- to create another CvRDT. data PNCounter a PNCounter :: !(GCounter a) -> !(GCounter a) -> PNCounter a [positive] :: PNCounter a -> !(GCounter a) [negative] :: PNCounter a -> !(GCounter a) instance GHC.Show.Show a => GHC.Show.Show (CRDT.PNCounter.Cv.Internal.PNCounter a) instance GHC.Classes.Eq a => GHC.Classes.Eq (CRDT.PNCounter.Cv.Internal.PNCounter a) instance GHC.Classes.Ord a => Data.Semigroup.Semigroup (CRDT.PNCounter.Cv.Internal.PNCounter a) instance GHC.Classes.Ord a => Data.Semilattice.Semilattice (CRDT.PNCounter.Cv.Internal.PNCounter a) module CRDT.PNCounter.Cv -- | Positive-negative counter. Allows incrementing and decrementing. Nice -- example of combining of existing CvRDT (GCounter in this case) -- to create another CvRDT. data PNCounter a -- | Initial state initial :: PNCounter a -- | Get value from the state query :: Num a => PNCounter a -> a -- | Decrement counter decrement :: Num a => Word -> PNCounter a -> PNCounter a -- | Increment counter increment :: Num a => Word -> PNCounter a -> PNCounter a module CRDT.Cm -- | Operation-based, or commutative (Cm) replicated data type. -- -- -- -- Idempotency doesn't need to hold. class CmRDT op where type State op :: Type where { type family State op :: Type; } -- | Apply operation to a value update :: CmRDT op => op -> State op -> State op module CRDT.GCounter.Cm -- | Grow-only counter. -- -- Commutativity: Increment obviously commutes with itself. data GCounter a Increment :: GCounter a -- | Initial state initial :: Num a => a instance GHC.Show.Show (CRDT.GCounter.Cm.GCounter a) instance GHC.Num.Num a => CRDT.Cm.CmRDT (CRDT.GCounter.Cm.GCounter a) module CRDT.LWW -- | Last write wins. Interesting, this type is both CmRDT and -- CvRDT. data LWW a Write :: !Timestamp -> !a -> LWW a [timestamp] :: LWW a -> !Timestamp [value] :: LWW a -> !a -- | Initialize state point :: Timestamp -> a -> LWW a -- | Change state write :: Ord a => Timestamp -> a -> LWW a -> LWW a -- | Query state query :: LWW a -> a instance GHC.Show.Show a => GHC.Show.Show (CRDT.LWW.LWW a) instance GHC.Classes.Ord a => GHC.Classes.Ord (CRDT.LWW.LWW a) instance GHC.Classes.Eq a => GHC.Classes.Eq (CRDT.LWW.LWW a) instance GHC.Classes.Ord a => Data.Semigroup.Semigroup (CRDT.LWW.LWW a) instance GHC.Classes.Ord a => CRDT.Cm.CmRDT (CRDT.LWW.LWW a) instance GHC.Classes.Ord a => Data.Semilattice.Semilattice (CRDT.LWW.LWW a) module CRDT.PNCounter.Cm -- | Positive-negative counter. Allows incrementing and decrementing. data PNCounter a Increment :: PNCounter a Decrement :: PNCounter a -- | Initial state initial :: Num a => a instance GHC.Show.Show (CRDT.PNCounter.Cm.PNCounter a) instance GHC.Enum.Enum (CRDT.PNCounter.Cm.PNCounter a) instance GHC.Enum.Bounded (CRDT.PNCounter.Cm.PNCounter a) instance GHC.Num.Num a => CRDT.Cm.CmRDT (CRDT.PNCounter.Cm.PNCounter a)