started on haskell code for codebase editor

This commit is contained in:
Paul Chiusano 2018-09-19 15:58:40 -04:00
parent 9e19f0cfb7
commit 42a73ce940
13 changed files with 172 additions and 3 deletions

5
.gitignore vendored
View File

@ -9,9 +9,6 @@ cabal-dev
*.un~
**/cache/**
**/build/**
store
codestore
codebase
tags
unison-src/.loaded
**cabal.sandbox.config
@ -20,6 +17,8 @@ blockstore
blockstore.leveldb
target
htags
scala-tags
haskell-tags
# Stack
.stack-work

View File

@ -0,0 +1,24 @@
module Unison.Codebase where
import qualified Unison.Term as Term
import qualified Unison.DataDeclaration as DD
import Unison.Reference (Reference)
import Unison.Codebase.Code (Code)
import Unison.Codebase.Branch (Branch)
import Unison.Codebase.Release (Release)
type DataDeclaration v a = DD.DataDeclaration' v a
type Term v a = Term.AnnotatedTerm v a
type Name = String
data Codebase m v a =
Codebase { getCode :: Reference -> m (Maybe (Code v a))
, putCode :: Code v a -> m Reference
, branches :: m [Name]
, getBranch :: Name -> m (Maybe (Branch v a))
, putBranch :: Name -> Branch v a -> m ()
, releases :: m [Name]
, getRelease :: Name -> m (Maybe (Release v a))
, putRelease :: Name -> Release v a -> m ()
}

View File

@ -0,0 +1,18 @@
module Unison.Codebase.Branch where
import Data.Map (Map)
import Unison.Codebase.Causal (Causal)
import Unison.Codebase.Conflicted (Conflicted)
import Unison.Codebase.Name (Name)
import Unison.Codebase.NameEdit (NameEdit)
import Unison.Codebase.TermEdit (TermEdit)
import Unison.Codebase.TypeEdit (TypeEdit)
import Unison.Reference (Reference)
data Branch v a =
Branch { namespace :: Map Name (Causal NameEdit)
, edited :: Map Reference (Causal (Conflicted TermEdit))
, editedDatas :: Map Reference (Causal (Conflicted TypeEdit))
, editedEffects :: Map Reference (Causal (Conflicted TypeEdit))
}

View File

@ -0,0 +1,45 @@
module Unison.Codebase.Causal where
import Prelude hiding (head, sequence)
import Data.List (sort)
import Unison.Hash (Hash)
import qualified Unison.Hashable as Hashable
import Unison.Hashable (Hashable)
data Causal e
= One { currentHash :: Hash, head :: e }
| Cons { currentHash :: Hash, head :: e, tail :: Causal e }
| Merge { currentHash :: Hash, head :: e, tail1 :: Causal e, tail2 :: Causal e }
instance Semigroup e => Semigroup (Causal e) where
a <> b
| before a b = b
| before b a = a
| otherwise = Merge (mixHashes [currentHash a, currentHash b])
(head a <> head b) a b
hash :: Hashable e => e -> Hash
hash = Hashable.accumulate'
-- commutative combine of a list of hashes
mixHashes :: [Hash] -> Hash
mixHashes = hash . sort
one :: Hashable e => e -> Causal e
one e = One (hash e) e
cons :: Hashable e => e -> Causal e -> Causal e
cons e tl = Cons (hash [hash e, currentHash tl]) e tl
sequence :: (Semigroup e, Hashable e) => Causal e -> Causal e -> Causal e
sequence a (One _ e) = cons e a
sequence a (Cons _ e tl) = cons e (sequence a tl)
sequence a (Merge _ _ l r) = sequence a l <> r
-- note: if causal had a `split` operation, we'd need to sequence on both sides
-- Does `h2` incorporate all of `h1`?
before :: Causal e -> Causal e -> Bool
before h1 h2 = go (currentHash h1) h2 where
go h1 (One h _) = h == h1
go h1 (Cons h _ tl) = h == h1 || go h1 tl
go h1 (Merge h _ left right) = h == h1 || go h1 left || go h1 right

View File

@ -0,0 +1,12 @@
module Unison.Codebase.Code where
import qualified Unison.Term as Term
import qualified Unison.DataDeclaration as DD
type DataDeclaration v a = DD.DataDeclaration' v a
type Term v a = Term.AnnotatedTerm v a
data Code v a
= Term (Term v a)
| DataDeclaration (DataDeclaration v a)

View File

@ -0,0 +1,12 @@
module Unison.Codebase.Conflicted where
import qualified Data.Set as Set
import Data.Set (Set)
data Conflicted a = One a | Many (Set a)
instance Ord a => Semigroup (Conflicted a) where
One a <> One a2 = if a == a2 then One a else Many (Set.fromList [a,a2])
One a <> Many as = Many (Set.insert a as)
Many as <> One a = Many (Set.insert a as)
Many as <> Many as2 = Many (as `Set.union` as2)

View File

@ -0,0 +1,3 @@
module Unison.Codebase.Name where
type Name = String

View File

@ -0,0 +1,7 @@
module Unison.Codebase.NameEdit where
import Data.Set (Set)
import Unison.Reference (Reference)
data NameEdit =
NameEdit { added :: Set Reference, removed :: Set Reference }

View File

@ -0,0 +1,21 @@
module Unison.Codebase.Release where
import Data.Map (Map)
import Unison.Codebase.Code (Code)
import Unison.Codebase.Name (Name)
import Unison.Codebase.TermEdit (TermEdit)
import Unison.Codebase.TypeEdit (TypeEdit)
import Unison.Reference (Reference)
import qualified Unison.DataDeclaration as DD
import qualified Unison.Term as Term
type DataDeclaration v a = DD.DataDeclaration' v a
type Term v a = Term.AnnotatedTerm v a
data Release v a =
Release { namespace :: Map Name (Code v a)
, edited :: Map Reference TermEdit
, editedDatas :: Map Reference TypeEdit
, editedEffects :: Map Reference TypeEdit }

View File

@ -0,0 +1,10 @@
module Unison.Codebase.TermEdit where
import Unison.Reference (Reference)
data TermEdit = Replace Reference Typing | Deprecate
-- Replacements with the Same type can be automatically propagated.
-- Replacements with a Subtype can be automatically propagated but may result in dependents getting more general types, so requires re-inference.
-- Replacements of a Different type need to be manually propagated by the programmer.
data Typing = Same | Subtype | Different

View File

@ -0,0 +1,5 @@
module Unison.Codebase.TypeEdit where
import Unison.Reference (Reference)
data TypeEdit = Replace Reference | Deprecated

View File

@ -23,6 +23,9 @@ newtype Hash = Hash { toBytes :: ByteString } deriving (Eq,Ord,Generic)
instance Show Hash where
show h = take 8 $ Text.unpack (base58 h)
instance H.Hashable Hash where
tokens h = [H.Bytes (toBytes h)]
fromBytesImpl :: ByteString -> Hash
fromBytesImpl = fromBytes

View File

@ -38,6 +38,16 @@ library
Unison.Blank
Unison.Builtin
Unison.Codecs
Unison.Codebase
Unison.Codebase.Branch
Unison.Codebase.Causal
Unison.Codebase.Code
Unison.Codebase.Conflicted
Unison.Codebase.Name
Unison.Codebase.NameEdit
Unison.Codebase.Release
Unison.Codebase.TermEdit
Unison.Codebase.TypeEdit
Unison.DataDeclaration
Unison.FileParser
Unison.FileParsers