{-# LANGUAGE GADTs #-} {-# LANGUAGE DeriveFunctor #-} {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE DeriveFoldable #-} {-# LANGUAGE DeriveTraversable #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE StandaloneDeriving #-} {-# LANGUAGE MultiParamTypeClasses #-} module Data.Crjdt.Types where import Data.String import Data.Text import Data.Void newtype Var = Variable { getName :: Text } deriving (Show, Eq, Ord) instance IsString Var where fromString = Variable . fromString data TaggedKey tag = TK { tag :: !tag , getKey :: !BasicKey } deriving (Eq, Ord, Functor, Foldable, Traversable) instance Show tag => Show (TaggedKey tag) where show (TK t k) = show (t, k) -- TODO: rethink about this type data Key tag where Key :: BasicKey -> Key Void TaggedKey :: TaggedKey tag -> Key tag data BasicKey = DocKey | Head | Tail | I Id | Str Text deriving (Show, Eq, Ord) instance (Ord tag, Eq tag) => Ord (Key tag) where (Key k) `compare` (Key k1) = k `compare` k1 (TaggedKey k) `compare` (TaggedKey k1) = k `compare` k1 instance IsString (Key Void) where fromString = Key . Str . fromString instance Show tag => Show (Key tag) where show (Key t) = show t show (TaggedKey taggedKey) = show taggedKey instance Eq tag => Eq (Key tag) where (Key t) == (Key t1) = t == t1 (TaggedKey t) == (TaggedKey t1) = t == t1 (Key _) == (TaggedKey _) = False (TaggedKey _) == (Key _) = False type ReplicaId = Integer type GlobalReplicaCounter = Integer newtype Id = Id { getId :: (GlobalReplicaCounter, ReplicaId) } deriving (Eq, Ord) instance Show Id where show = show . getId sequenceNumber = fst . getId replicaNumber = snd . getId mkId sn rid = Id (sn, rid) tagWith :: tag -> BasicKey -> Key tag tagWith t = TaggedKey . TK t getTag :: Key tag -> tag getTag (TaggedKey (TK t _)) = t basicKey :: Key tag -> BasicKey basicKey (Key k) = k basicKey (TaggedKey (TK _ k)) = k unTag :: Key tag -> Key Void unTag (Key k) = Key k unTag (TaggedKey (TK _ k)) = Key k reTag :: a -> Key Void -> Key a reTag given (Key k) = tagWith given k reTag given (TaggedKey (TK _ k)) = tagWith given k