packages feed

crdt 0.1 → 0.2

raw patch · 13 files changed

+65/−40 lines, 13 filesdep −derivePVP ok

version bump matches the API change (PVP)

Dependencies removed: derive

API changes (from Hackage documentation)

- CRDT.Cv: class Semigroup state => CvRDT state
- CRDT.GCounter.Cv.Internal: instance GHC.Classes.Ord a => CRDT.Cv.CvRDT (CRDT.GCounter.Cv.Internal.GCounter a)
- CRDT.LWW: instance GHC.Classes.Ord a => CRDT.Cv.CvRDT (CRDT.LWW.LWW a)
- CRDT.PNCounter.Cv.Internal: instance GHC.Classes.Ord a => CRDT.Cv.CvRDT (CRDT.PNCounter.Cv.Internal.PNCounter a)
+ CRDT.Cv: type CvRDT = Semilattice
+ CRDT.GCounter.Cv.Internal: instance GHC.Classes.Ord a => Data.Semilattice.Semilattice (CRDT.GCounter.Cv.Internal.GCounter a)
+ CRDT.GCounter.Cv.Internal: instance GHC.Show.Show a => GHC.Show.Show (CRDT.GCounter.Cv.Internal.GCounter a)
+ CRDT.LWW: instance GHC.Classes.Ord a => Data.Semilattice.Semilattice (CRDT.LWW.LWW a)
+ CRDT.LWW: instance GHC.Show.Show a => GHC.Show.Show (CRDT.LWW.LWW a)
+ CRDT.PNCounter.Cm: instance GHC.Enum.Bounded (CRDT.PNCounter.Cm.PNCounter a)
+ CRDT.PNCounter.Cm: instance GHC.Enum.Enum (CRDT.PNCounter.Cm.PNCounter a)
+ CRDT.PNCounter.Cm: instance GHC.Show.Show (CRDT.PNCounter.Cm.PNCounter a)
+ CRDT.PNCounter.Cv.Internal: instance GHC.Classes.Ord a => Data.Semilattice.Semilattice (CRDT.PNCounter.Cv.Internal.PNCounter a)
+ CRDT.PNCounter.Cv.Internal: instance GHC.Show.Show a => GHC.Show.Show (CRDT.PNCounter.Cv.Internal.PNCounter a)
+ Data.Semilattice: (<>) :: Semilattice a => a -> a -> a
+ Data.Semilattice: class Semigroup a => Semilattice a
+ Data.Semilattice: infixr 6 <>

Files

crdt.cabal view
@@ -3,7 +3,7 @@ -- see: https://github.com/sol/hpack  name:           crdt-version:        0.1+version:        0.2 synopsis:       Conflict-free replicated data types description:    Definitions of CmRDT and CvRDT. Implementations for some classic CRDTs. category:       Distributed Systems@@ -35,6 +35,7 @@       CRDT.PNCounter.Cm       CRDT.PNCounter.Cv       CRDT.PNCounter.Cv.Internal+      Data.Semilattice   default-language: Haskell2010  test-suite test@@ -45,7 +46,6 @@   build-depends:       base >= 4.9 && < 4.10     , vector-    , derive     , QuickCheck     , tasty     , tasty-quickcheck
lib/CRDT/Cm.hs view
@@ -13,6 +13,8 @@ [Commutativity law]      @'update' op1 . 'update' op2 == 'update' op2 . 'update' op1@++Idempotency doesn't need to hold. -} class CmRDT op where 
lib/CRDT/Cv.hs view
@@ -1,8 +1,10 @@+{-# LANGUAGE ConstraintKinds #-}+ module CRDT.Cv     ( CvRDT     ) where -import Data.Semigroup (Semigroup (..))+import Data.Semilattice (Semilattice)  {- | State-based, or convergent (Cv) replicated data type.@@ -12,14 +14,6 @@ Query function is not needed. State itself is exposed. In other words, @query = 'id'@. -Laws:--[commutativity]--    @x '<>' y == y '<>' x@--[idempotency]--    @x '<>' x == x@+Actually, a CvRDT is nothing more a 'Semilattice'. -}-class Semigroup state => CvRDT state+type CvRDT = Semilattice
lib/CRDT/GCounter/Cv.hs view
@@ -1,8 +1,9 @@ module CRDT.GCounter.Cv     ( GCounter-    , increment     , initial     , query+    -- * Operation+    , increment     ) where  import           Data.Monoid         ((<>))
lib/CRDT/GCounter/Cv/Internal.hs view
@@ -8,7 +8,7 @@  -- | Grow-only counter. newtype GCounter a = GCounter (Vector a)-    deriving Eq+    deriving (Eq, Show)  instance Ord a => Semigroup (GCounter a) where     GCounter x <> GCounter y = GCounter $ Vector.zipWith max x y
lib/CRDT/LWW.hs view
@@ -19,7 +19,7 @@     { timestamp :: !Timestamp     , value     :: !a     }-    deriving (Eq, Ord)+    deriving (Eq, Ord, Show)  instance Ord a => Semigroup (LWW a) where     (<>) = max
lib/CRDT/PNCounter/Cm.hs view
@@ -10,6 +10,7 @@  -- | Positive-negative counter. Allows incrementing and decrementing. data PNCounter a = Increment | Decrement+    deriving (Bounded, Enum, Show)  instance Num a => CmRDT (PNCounter a) where     type State (PNCounter a) = a
lib/CRDT/PNCounter/Cv.hs view
@@ -2,10 +2,11 @@  module CRDT.PNCounter.Cv     ( PNCounter-    , decrement-    , increment     , initial     , query+    -- * Operations+    , decrement+    , increment     ) where  import qualified CRDT.GCounter.Cv as GCounter
lib/CRDT/PNCounter/Cv/Internal.hs view
@@ -14,7 +14,7 @@     { positive :: !(GCounter a)     , negative :: !(GCounter a)     }-    deriving Eq+    deriving (Eq, Show)  instance Ord a => Semigroup (PNCounter a) where     PNCounter p1 n1 <> PNCounter p2 n2 = PNCounter (p1 <> p2) (n1 <> n2)
+ lib/Data/Semilattice.hs view
@@ -0,0 +1,32 @@+module Data.Semilattice+    ( Semilattice+    , (<>)+    ) where++import           Data.Semigroup (Semigroup)+import qualified Data.Semigroup as Semigroup++{- |+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:++[commutativity]++    @x '<>' y == y '<>' x@++[idempotency]++    @x '<>' x == x@+-}+class Semigroup a => Semilattice a++-- | Just ('Semigroup.<>'), specialized to 'Semilattice'.+(<>) :: Semilattice a => a -> a -> a+(<>) = (Semigroup.<>)+infixr 6 <>+{-# INLINE (<>) #-}
test/Instances/Cm.hs view
@@ -1,19 +1,14 @@ {-# OPTIONS_GHC -Wno-orphans #-} -{-# LANGUAGE GeneralizedNewtypeDeriving #-}-{-# LANGUAGE StandaloneDeriving #-}-{-# LANGUAGE TemplateHaskell #-}- module Instances.Cm () where -import Data.DeriveTH   (derives, makeArbitrary)-import Test.QuickCheck (Arbitrary, arbitrary, choose)+import Test.QuickCheck (Arbitrary, arbitrary, arbitraryBoundedEnum)  import CRDT.LWW          (LWW (..)) import CRDT.PNCounter.Cm (PNCounter (..)) -derives [makeArbitrary] [''PNCounter, ''LWW]--deriving instance Show (PNCounter a)+instance Arbitrary (PNCounter a) where+    arbitrary = arbitraryBoundedEnum -deriving instance Show a => Show (LWW a)+instance Arbitrary a => Arbitrary (LWW a) where+    arbitrary = Write <$> arbitrary <*> arbitrary
test/Instances/Cv.hs view
@@ -17,9 +17,5 @@  deriving instance Arbitrary a => Arbitrary (GCounter a) -deriving instance Show a => Show (GCounter a)- instance Arbitrary a => Arbitrary (PNCounter a) where     arbitrary = PNCounter <$> arbitrary <*> arbitrary--deriving instance Show a => Show (PNCounter a)
test/Main.hs view
@@ -2,7 +2,7 @@ {-# LANGUAGE ScopedTypeVariables #-}  import Data.Proxy            (Proxy (..))-import Data.Semigroup        ((<>))+import Data.Semilattice      (Semilattice, (<>)) import Test.QuickCheck       (Arbitrary, Small (..)) import Test.Tasty            (TestTree, defaultMain, testGroup) import Test.Tasty.QuickCheck (testProperty)@@ -42,18 +42,18 @@                 PncCv.query (PncCv.decrement i c) == pred (PncCv.query c)         ]     , testGroup "Cm"-        [ cmrdtCommutativity (Proxy :: Proxy (PncCm.PNCounter Int)) ]+        [ cmrdtLaws (Proxy :: Proxy (PncCm.PNCounter Int)) ]     ]  lww :: TestTree lww = testGroup "LWW"-    [ testGroup "Cm" [ cmrdtCommutativity (Proxy :: Proxy (LWW Int)) ]+    [ testGroup "Cm" [ cmrdtLaws (Proxy :: Proxy (LWW Int)) ]     , testGroup "Cv" [ cvrdtLaws (Proxy :: Proxy (LWW Int)) ]     ] -cvrdtLaws+semilatticeLaws     :: forall a . (Arbitrary a, CvRDT a, Eq a, Show a) => Proxy a -> TestTree-cvrdtLaws _ = testGroup "CvRDT laws"+semilatticeLaws _ = testGroup "Semilattice laws"     [ testProperty "associativity" associativity     , testProperty "commutativity" commutativity     , testProperty "idempotency"   idempotency@@ -68,13 +68,16 @@     idempotency :: a -> Bool     idempotency x = x <> x == x -cmrdtCommutativity+cvrdtLaws :: (Arbitrary a, Semilattice a, Eq a, Show a) => Proxy a -> TestTree+cvrdtLaws = semilatticeLaws++cmrdtLaws     :: forall op     . ( Arbitrary op, CmRDT op, Show op       , Arbitrary (State op), Eq (State op), Show (State op)       )     => Proxy op -> TestTree-cmrdtCommutativity _ = testProperty "CmRDT law: commutativity" commutativity+cmrdtLaws _ = testProperty "CmRDT law: commutativity" commutativity   where     commutativity :: op -> op -> State op -> Bool     commutativity op1 op2 x =