{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE TemplateHaskell #-}

module Unison.Codebase.Patch where

import Control.Lens hiding (children, cons, transform)
import Data.Set qualified as Set
import Unison.Codebase.TermEdit (TermEdit, Typing (Same))
import Unison.Codebase.TermEdit qualified as TermEdit
import Unison.Codebase.TypeEdit (TypeEdit)
import Unison.Codebase.TypeEdit qualified as TypeEdit
import Unison.LabeledDependency (LabeledDependency)
import Unison.LabeledDependency qualified as LD
import Unison.Prelude hiding (empty)
import Unison.Reference (Reference)
import Unison.Util.Relation (Relation)
import Unison.Util.Relation qualified as R
import Prelude hiding (head, read, subtract)

data Patch = Patch
  { Patch -> Relation Reference TermEdit
_termEdits :: Relation Reference TermEdit,
    Patch -> Relation Reference TypeEdit
_typeEdits :: Relation Reference TypeEdit
  }
  deriving (Patch -> Patch -> Bool
(Patch -> Patch -> Bool) -> (Patch -> Patch -> Bool) -> Eq Patch
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Patch -> Patch -> Bool
== :: Patch -> Patch -> Bool
$c/= :: Patch -> Patch -> Bool
/= :: Patch -> Patch -> Bool
Eq, Eq Patch
Eq Patch =>
(Patch -> Patch -> Ordering)
-> (Patch -> Patch -> Bool)
-> (Patch -> Patch -> Bool)
-> (Patch -> Patch -> Bool)
-> (Patch -> Patch -> Bool)
-> (Patch -> Patch -> Patch)
-> (Patch -> Patch -> Patch)
-> Ord Patch
Patch -> Patch -> Bool
Patch -> Patch -> Ordering
Patch -> Patch -> Patch
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: Patch -> Patch -> Ordering
compare :: Patch -> Patch -> Ordering
$c< :: Patch -> Patch -> Bool
< :: Patch -> Patch -> Bool
$c<= :: Patch -> Patch -> Bool
<= :: Patch -> Patch -> Bool
$c> :: Patch -> Patch -> Bool
> :: Patch -> Patch -> Bool
$c>= :: Patch -> Patch -> Bool
>= :: Patch -> Patch -> Bool
$cmax :: Patch -> Patch -> Patch
max :: Patch -> Patch -> Patch
$cmin :: Patch -> Patch -> Patch
min :: Patch -> Patch -> Patch
Ord, Int -> Patch -> ShowS
[Patch] -> ShowS
Patch -> String
(Int -> Patch -> ShowS)
-> (Patch -> String) -> ([Patch] -> ShowS) -> Show Patch
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Patch -> ShowS
showsPrec :: Int -> Patch -> ShowS
$cshow :: Patch -> String
show :: Patch -> String
$cshowList :: [Patch] -> ShowS
showList :: [Patch] -> ShowS
Show)

data PatchDiff = PatchDiff
  { PatchDiff -> Relation Reference TermEdit
_addedTermEdits :: Relation Reference TermEdit,
    PatchDiff -> Relation Reference TypeEdit
_addedTypeEdits :: Relation Reference TypeEdit,
    PatchDiff -> Relation Reference TermEdit
_removedTermEdits :: Relation Reference TermEdit,
    PatchDiff -> Relation Reference TypeEdit
_removedTypeEdits :: Relation Reference TypeEdit
  }
  deriving (PatchDiff -> PatchDiff -> Bool
(PatchDiff -> PatchDiff -> Bool)
-> (PatchDiff -> PatchDiff -> Bool) -> Eq PatchDiff
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: PatchDiff -> PatchDiff -> Bool
== :: PatchDiff -> PatchDiff -> Bool
$c/= :: PatchDiff -> PatchDiff -> Bool
/= :: PatchDiff -> PatchDiff -> Bool
Eq, Eq PatchDiff
Eq PatchDiff =>
(PatchDiff -> PatchDiff -> Ordering)
-> (PatchDiff -> PatchDiff -> Bool)
-> (PatchDiff -> PatchDiff -> Bool)
-> (PatchDiff -> PatchDiff -> Bool)
-> (PatchDiff -> PatchDiff -> Bool)
-> (PatchDiff -> PatchDiff -> PatchDiff)
-> (PatchDiff -> PatchDiff -> PatchDiff)
-> Ord PatchDiff
PatchDiff -> PatchDiff -> Bool
PatchDiff -> PatchDiff -> Ordering
PatchDiff -> PatchDiff -> PatchDiff
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: PatchDiff -> PatchDiff -> Ordering
compare :: PatchDiff -> PatchDiff -> Ordering
$c< :: PatchDiff -> PatchDiff -> Bool
< :: PatchDiff -> PatchDiff -> Bool
$c<= :: PatchDiff -> PatchDiff -> Bool
<= :: PatchDiff -> PatchDiff -> Bool
$c> :: PatchDiff -> PatchDiff -> Bool
> :: PatchDiff -> PatchDiff -> Bool
$c>= :: PatchDiff -> PatchDiff -> Bool
>= :: PatchDiff -> PatchDiff -> Bool
$cmax :: PatchDiff -> PatchDiff -> PatchDiff
max :: PatchDiff -> PatchDiff -> PatchDiff
$cmin :: PatchDiff -> PatchDiff -> PatchDiff
min :: PatchDiff -> PatchDiff -> PatchDiff
Ord, Int -> PatchDiff -> ShowS
[PatchDiff] -> ShowS
PatchDiff -> String
(Int -> PatchDiff -> ShowS)
-> (PatchDiff -> String)
-> ([PatchDiff] -> ShowS)
-> Show PatchDiff
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> PatchDiff -> ShowS
showsPrec :: Int -> PatchDiff -> ShowS
$cshow :: PatchDiff -> String
show :: PatchDiff -> String
$cshowList :: [PatchDiff] -> ShowS
showList :: [PatchDiff] -> ShowS
Show)

makeLenses ''Patch
makeLenses ''PatchDiff

diff :: Patch -> Patch -> PatchDiff
diff :: Patch -> Patch -> PatchDiff
diff Patch
new Patch
old =
  PatchDiff
    { $sel:_addedTermEdits:PatchDiff :: Relation Reference TermEdit
_addedTermEdits = Relation Reference TermEdit
-> Relation Reference TermEdit -> Relation Reference TermEdit
forall a b.
(Ord a, Ord b) =>
Relation a b -> Relation a b -> Relation a b
R.difference (Getting
  (Relation Reference TermEdit) Patch (Relation Reference TermEdit)
-> Patch -> Relation Reference TermEdit
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting
  (Relation Reference TermEdit) Patch (Relation Reference TermEdit)
Lens' Patch (Relation Reference TermEdit)
termEdits Patch
new) (Getting
  (Relation Reference TermEdit) Patch (Relation Reference TermEdit)
-> Patch -> Relation Reference TermEdit
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting
  (Relation Reference TermEdit) Patch (Relation Reference TermEdit)
Lens' Patch (Relation Reference TermEdit)
termEdits Patch
old),
      $sel:_addedTypeEdits:PatchDiff :: Relation Reference TypeEdit
_addedTypeEdits = Relation Reference TypeEdit
-> Relation Reference TypeEdit -> Relation Reference TypeEdit
forall a b.
(Ord a, Ord b) =>
Relation a b -> Relation a b -> Relation a b
R.difference (Getting
  (Relation Reference TypeEdit) Patch (Relation Reference TypeEdit)
-> Patch -> Relation Reference TypeEdit
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting
  (Relation Reference TypeEdit) Patch (Relation Reference TypeEdit)
Lens' Patch (Relation Reference TypeEdit)
typeEdits Patch
new) (Getting
  (Relation Reference TypeEdit) Patch (Relation Reference TypeEdit)
-> Patch -> Relation Reference TypeEdit
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting
  (Relation Reference TypeEdit) Patch (Relation Reference TypeEdit)
Lens' Patch (Relation Reference TypeEdit)
typeEdits Patch
old),
      $sel:_removedTypeEdits:PatchDiff :: Relation Reference TypeEdit
_removedTypeEdits = Relation Reference TypeEdit
-> Relation Reference TypeEdit -> Relation Reference TypeEdit
forall a b.
(Ord a, Ord b) =>
Relation a b -> Relation a b -> Relation a b
R.difference (Getting
  (Relation Reference TypeEdit) Patch (Relation Reference TypeEdit)
-> Patch -> Relation Reference TypeEdit
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting
  (Relation Reference TypeEdit) Patch (Relation Reference TypeEdit)
Lens' Patch (Relation Reference TypeEdit)
typeEdits Patch
old) (Getting
  (Relation Reference TypeEdit) Patch (Relation Reference TypeEdit)
-> Patch -> Relation Reference TypeEdit
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting
  (Relation Reference TypeEdit) Patch (Relation Reference TypeEdit)
Lens' Patch (Relation Reference TypeEdit)
typeEdits Patch
new),
      $sel:_removedTermEdits:PatchDiff :: Relation Reference TermEdit
_removedTermEdits = Relation Reference TermEdit
-> Relation Reference TermEdit -> Relation Reference TermEdit
forall a b.
(Ord a, Ord b) =>
Relation a b -> Relation a b -> Relation a b
R.difference (Getting
  (Relation Reference TermEdit) Patch (Relation Reference TermEdit)
-> Patch -> Relation Reference TermEdit
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting
  (Relation Reference TermEdit) Patch (Relation Reference TermEdit)
Lens' Patch (Relation Reference TermEdit)
termEdits Patch
old) (Getting
  (Relation Reference TermEdit) Patch (Relation Reference TermEdit)
-> Patch -> Relation Reference TermEdit
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting
  (Relation Reference TermEdit) Patch (Relation Reference TermEdit)
Lens' Patch (Relation Reference TermEdit)
termEdits Patch
new)
    }

labeledDependencies :: Patch -> Set LabeledDependency
labeledDependencies :: Patch -> Set LabeledDependency
labeledDependencies Patch {Relation Reference TermEdit
Relation Reference TypeEdit
$sel:_termEdits:Patch :: Patch -> Relation Reference TermEdit
$sel:_typeEdits:Patch :: Patch -> Relation Reference TypeEdit
_termEdits :: Relation Reference TermEdit
_typeEdits :: Relation Reference TypeEdit
..} =
  (Reference -> LabeledDependency)
-> Set Reference -> Set LabeledDependency
forall b a. Ord b => (a -> b) -> Set a -> Set b
Set.map Reference -> LabeledDependency
LD.termRef (Relation Reference TermEdit -> Set Reference
forall a b. Relation a b -> Set a
R.dom Relation Reference TermEdit
_termEdits)
    Set LabeledDependency
-> Set LabeledDependency -> Set LabeledDependency
forall a. Semigroup a => a -> a -> a
<> [LabeledDependency] -> Set LabeledDependency
forall a. Ord a => [a] -> Set a
Set.fromList
      ((Reference -> LabeledDependency)
-> [Reference] -> [LabeledDependency]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Reference -> LabeledDependency
LD.termRef ([Reference] -> [LabeledDependency])
-> [Reference] -> [LabeledDependency]
forall a b. (a -> b) -> a -> b
$ TermEdit -> [Reference]
TermEdit.references (TermEdit -> [Reference]) -> [TermEdit] -> [Reference]
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Set TermEdit -> [TermEdit]
forall a. Set a -> [a]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList (Relation Reference TermEdit -> Set TermEdit
forall a b. Relation a b -> Set b
R.ran Relation Reference TermEdit
_termEdits))
    Set LabeledDependency
-> Set LabeledDependency -> Set LabeledDependency
forall a. Semigroup a => a -> a -> a
<> (Reference -> LabeledDependency)
-> Set Reference -> Set LabeledDependency
forall b a. Ord b => (a -> b) -> Set a -> Set b
Set.map Reference -> LabeledDependency
LD.typeRef (Relation Reference TypeEdit -> Set Reference
forall a b. Relation a b -> Set a
R.dom Relation Reference TypeEdit
_typeEdits)
    Set LabeledDependency
-> Set LabeledDependency -> Set LabeledDependency
forall a. Semigroup a => a -> a -> a
<> [LabeledDependency] -> Set LabeledDependency
forall a. Ord a => [a] -> Set a
Set.fromList
      ((Reference -> LabeledDependency)
-> [Reference] -> [LabeledDependency]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Reference -> LabeledDependency
LD.typeRef ([Reference] -> [LabeledDependency])
-> [Reference] -> [LabeledDependency]
forall a b. (a -> b) -> a -> b
$ TypeEdit -> [Reference]
TypeEdit.references (TypeEdit -> [Reference]) -> [TypeEdit] -> [Reference]
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Set TypeEdit -> [TypeEdit]
forall a. Set a -> [a]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList (Relation Reference TypeEdit -> Set TypeEdit
forall a b. Relation a b -> Set b
R.ran Relation Reference TypeEdit
_typeEdits))

empty :: Patch
empty :: Patch
empty = Relation Reference TermEdit -> Relation Reference TypeEdit -> Patch
Patch Relation Reference TermEdit
forall a. Monoid a => a
mempty Relation Reference TypeEdit
forall a. Monoid a => a
mempty

isEmpty :: Patch -> Bool
isEmpty :: Patch -> Bool
isEmpty Patch
p = Patch
p Patch -> Patch -> Bool
forall a. Eq a => a -> a -> Bool
== Patch
empty

allReferences :: Patch -> Set Reference
allReferences :: Patch -> Set Reference
allReferences Patch
p = Patch -> Set Reference
typeReferences Patch
p Set Reference -> Set Reference -> Set Reference
forall a. Semigroup a => a -> a -> a
<> Patch -> Set Reference
termReferences Patch
p
  where
    typeReferences :: Patch -> Set Reference
typeReferences Patch
p =
      [Reference] -> Set Reference
forall a. Ord a => [a] -> Set a
Set.fromList
        [ Reference
r | (Reference
old, TypeEdit.Replace Reference
new) <- Relation Reference TypeEdit -> [(Reference, TypeEdit)]
forall a b. Relation a b -> [(a, b)]
R.toList (Patch -> Relation Reference TypeEdit
_typeEdits Patch
p), Reference
r <- [Reference
old, Reference
new]
        ]
    termReferences :: Patch -> Set Reference
termReferences Patch
p =
      [Reference] -> Set Reference
forall a. Ord a => [a] -> Set a
Set.fromList
        [ Reference
r | (Reference
old, TermEdit.Replace Reference
new Typing
_) <- Relation Reference TermEdit -> [(Reference, TermEdit)]
forall a b. Relation a b -> [(a, b)]
R.toList (Patch -> Relation Reference TermEdit
_termEdits Patch
p), Reference
r <- [Reference
old, Reference
new]
        ]

-- | Returns the set of references which are the target of an arrow in the patch
allReferenceTargets :: Patch -> Set Reference
allReferenceTargets :: Patch -> Set Reference
allReferenceTargets Patch
p = Patch -> Set Reference
typeReferences Patch
p Set Reference -> Set Reference -> Set Reference
forall a. Semigroup a => a -> a -> a
<> Patch -> Set Reference
termReferences Patch
p
  where
    typeReferences :: Patch -> Set Reference
typeReferences Patch
p =
      [Reference] -> Set Reference
forall a. Ord a => [a] -> Set a
Set.fromList
        [Reference
new | (Reference
_, TypeEdit.Replace Reference
new) <- Relation Reference TypeEdit -> [(Reference, TypeEdit)]
forall a b. Relation a b -> [(a, b)]
R.toList (Patch -> Relation Reference TypeEdit
_typeEdits Patch
p)]
    termReferences :: Patch -> Set Reference
termReferences Patch
p =
      [Reference] -> Set Reference
forall a. Ord a => [a] -> Set a
Set.fromList
        [Reference
new | (Reference
_, TermEdit.Replace Reference
new Typing
_) <- Relation Reference TermEdit -> [(Reference, TermEdit)]
forall a b. Relation a b -> [(a, b)]
R.toList (Patch -> Relation Reference TermEdit
_termEdits Patch
p)]

updateTerm ::
  (Reference -> Reference -> Typing) ->
  Reference ->
  TermEdit ->
  Patch ->
  Patch
updateTerm :: (Reference -> Reference -> Typing)
-> Reference -> TermEdit -> Patch -> Patch
updateTerm Reference -> Reference -> Typing
typing Reference
r TermEdit
edit Patch
p =
  -- get D ~= lookupRan r
  -- for each d ∈ D, remove (d, r) and add (d, r')
  -- add (r, r') and remove (r', r')
  let deleteCycle :: Relation Reference TermEdit -> Relation Reference TermEdit
deleteCycle = case TermEdit
edit of
        TermEdit
TermEdit.Deprecate -> Relation Reference TermEdit -> Relation Reference TermEdit
forall a. a -> a
id
        TermEdit.Replace Reference
r' Typing
_ -> Reference
-> TermEdit
-> Relation Reference TermEdit
-> Relation Reference TermEdit
forall a b.
(Ord a, Ord b) =>
a -> b -> Relation a b -> Relation a b
R.delete Reference
r' (Reference -> Typing -> TermEdit
TermEdit.Replace Reference
r' Typing
Same)
      edits' :: Relation Reference TermEdit
      edits' :: Relation Reference TermEdit
edits' = Relation Reference TermEdit -> Relation Reference TermEdit
deleteCycle (Relation Reference TermEdit -> Relation Reference TermEdit)
-> (Relation Reference TermEdit -> Relation Reference TermEdit)
-> Relation Reference TermEdit
-> Relation Reference TermEdit
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Reference
-> TermEdit
-> Relation Reference TermEdit
-> Relation Reference TermEdit
forall a b.
(Ord a, Ord b) =>
a -> b -> Relation a b -> Relation a b
R.insert Reference
r TermEdit
edit (Relation Reference TermEdit -> Relation Reference TermEdit)
-> (Relation Reference TermEdit -> Relation Reference TermEdit)
-> Relation Reference TermEdit
-> Relation Reference TermEdit
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((Reference, TermEdit) -> (Reference, TermEdit))
-> Relation Reference TermEdit -> Relation Reference TermEdit
forall a b c d.
(Ord a, Ord b, Ord c, Ord d) =>
((a, b) -> (c, d)) -> Relation a b -> Relation c d
R.map (Reference, TermEdit) -> (Reference, TermEdit)
f (Relation Reference TermEdit -> Relation Reference TermEdit)
-> Relation Reference TermEdit -> Relation Reference TermEdit
forall a b. (a -> b) -> a -> b
$ Patch -> Relation Reference TermEdit
_termEdits Patch
p
      f :: (Reference, TermEdit) -> (Reference, TermEdit)
f (Reference
x, TermEdit.Replace Reference
y Typing
_) | Reference
y Reference -> Reference -> Bool
forall a. Eq a => a -> a -> Bool
== Reference
r = case TermEdit
edit of
        TermEdit.Replace Reference
r' Typing
_ -> (Reference
x, Reference -> Typing -> TermEdit
TermEdit.Replace Reference
r' (Reference -> Reference -> Typing
typing Reference
x Reference
r'))
        TermEdit
TermEdit.Deprecate -> (Reference
x, TermEdit
TermEdit.Deprecate)
      f (Reference, TermEdit)
p = (Reference, TermEdit)
p
   in Patch
p {_termEdits = edits'}

updateType :: Reference -> TypeEdit -> Patch -> Patch
updateType :: Reference -> TypeEdit -> Patch -> Patch
updateType Reference
r TypeEdit
edit Patch
p =
  let deleteCycle :: Relation Reference TypeEdit -> Relation Reference TypeEdit
deleteCycle = case TypeEdit
edit of
        TypeEdit
TypeEdit.Deprecate -> Relation Reference TypeEdit -> Relation Reference TypeEdit
forall a. a -> a
id
        TypeEdit.Replace Reference
r' -> Reference
-> TypeEdit
-> Relation Reference TypeEdit
-> Relation Reference TypeEdit
forall a b.
(Ord a, Ord b) =>
a -> b -> Relation a b -> Relation a b
R.delete Reference
r' (Reference -> TypeEdit
TypeEdit.Replace Reference
r')
      edits' :: Relation Reference TypeEdit
      edits' :: Relation Reference TypeEdit
edits' = Relation Reference TypeEdit -> Relation Reference TypeEdit
deleteCycle (Relation Reference TypeEdit -> Relation Reference TypeEdit)
-> (Relation Reference TypeEdit -> Relation Reference TypeEdit)
-> Relation Reference TypeEdit
-> Relation Reference TypeEdit
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Reference
-> TypeEdit
-> Relation Reference TypeEdit
-> Relation Reference TypeEdit
forall a b.
(Ord a, Ord b) =>
a -> b -> Relation a b -> Relation a b
R.insert Reference
r TypeEdit
edit (Relation Reference TypeEdit -> Relation Reference TypeEdit)
-> (Relation Reference TypeEdit -> Relation Reference TypeEdit)
-> Relation Reference TypeEdit
-> Relation Reference TypeEdit
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((Reference, TypeEdit) -> (Reference, TypeEdit))
-> Relation Reference TypeEdit -> Relation Reference TypeEdit
forall a b c d.
(Ord a, Ord b, Ord c, Ord d) =>
((a, b) -> (c, d)) -> Relation a b -> Relation c d
R.map (Reference, TypeEdit) -> (Reference, TypeEdit)
f (Relation Reference TypeEdit -> Relation Reference TypeEdit)
-> Relation Reference TypeEdit -> Relation Reference TypeEdit
forall a b. (a -> b) -> a -> b
$ Patch -> Relation Reference TypeEdit
_typeEdits Patch
p
      f :: (Reference, TypeEdit) -> (Reference, TypeEdit)
f (Reference
x, TypeEdit.Replace Reference
y) | Reference
y Reference -> Reference -> Bool
forall a. Eq a => a -> a -> Bool
== Reference
r = case TypeEdit
edit of
        TypeEdit.Replace Reference
r' -> (Reference
x, Reference -> TypeEdit
TypeEdit.Replace Reference
r')
        TypeEdit
TypeEdit.Deprecate -> (Reference
x, TypeEdit
TypeEdit.Deprecate)
      f (Reference, TypeEdit)
p = (Reference, TypeEdit)
p
   in Patch
p {_typeEdits = edits'}

conflicts :: Patch -> Patch
conflicts :: Patch -> Patch
conflicts Patch {Relation Reference TermEdit
Relation Reference TypeEdit
$sel:_termEdits:Patch :: Patch -> Relation Reference TermEdit
$sel:_typeEdits:Patch :: Patch -> Relation Reference TypeEdit
_termEdits :: Relation Reference TermEdit
_typeEdits :: Relation Reference TypeEdit
..} =
  Relation Reference TermEdit -> Relation Reference TypeEdit -> Patch
Patch (Relation Reference TermEdit -> Relation Reference TermEdit
forall a b. (Ord a, Ord b) => Relation a b -> Relation a b
R.filterManyDom Relation Reference TermEdit
_termEdits) (Relation Reference TypeEdit -> Relation Reference TypeEdit
forall a b. (Ord a, Ord b) => Relation a b -> Relation a b
R.filterManyDom Relation Reference TypeEdit
_typeEdits)

instance Semigroup Patch where
  Patch
a <> :: Patch -> Patch -> Patch
<> Patch
b =
    Relation Reference TermEdit -> Relation Reference TypeEdit -> Patch
Patch
      (Patch -> Relation Reference TermEdit
_termEdits Patch
a Relation Reference TermEdit
-> Relation Reference TermEdit -> Relation Reference TermEdit
forall a. Semigroup a => a -> a -> a
<> Patch -> Relation Reference TermEdit
_termEdits Patch
b)
      (Patch -> Relation Reference TypeEdit
_typeEdits Patch
a Relation Reference TypeEdit
-> Relation Reference TypeEdit -> Relation Reference TypeEdit
forall a. Semigroup a => a -> a -> a
<> Patch -> Relation Reference TypeEdit
_typeEdits Patch
b)

instance Monoid Patch where
  mempty :: Patch
mempty = Relation Reference TermEdit -> Relation Reference TypeEdit -> Patch
Patch Relation Reference TermEdit
forall a. Monoid a => a
mempty Relation Reference TypeEdit
forall a. Monoid a => a
mempty

instance Semigroup PatchDiff where
  PatchDiff
a <> :: PatchDiff -> PatchDiff -> PatchDiff
<> PatchDiff
b =
    PatchDiff
      { $sel:_addedTermEdits:PatchDiff :: Relation Reference TermEdit
_addedTermEdits = PatchDiff -> Relation Reference TermEdit
_addedTermEdits PatchDiff
a Relation Reference TermEdit
-> Relation Reference TermEdit -> Relation Reference TermEdit
forall a. Semigroup a => a -> a -> a
<> PatchDiff -> Relation Reference TermEdit
_addedTermEdits PatchDiff
b,
        $sel:_addedTypeEdits:PatchDiff :: Relation Reference TypeEdit
_addedTypeEdits = PatchDiff -> Relation Reference TypeEdit
_addedTypeEdits PatchDiff
a Relation Reference TypeEdit
-> Relation Reference TypeEdit -> Relation Reference TypeEdit
forall a. Semigroup a => a -> a -> a
<> PatchDiff -> Relation Reference TypeEdit
_addedTypeEdits PatchDiff
b,
        $sel:_removedTermEdits:PatchDiff :: Relation Reference TermEdit
_removedTermEdits = PatchDiff -> Relation Reference TermEdit
_removedTermEdits PatchDiff
a Relation Reference TermEdit
-> Relation Reference TermEdit -> Relation Reference TermEdit
forall a. Semigroup a => a -> a -> a
<> PatchDiff -> Relation Reference TermEdit
_removedTermEdits PatchDiff
b,
        $sel:_removedTypeEdits:PatchDiff :: Relation Reference TypeEdit
_removedTypeEdits = PatchDiff -> Relation Reference TypeEdit
_removedTypeEdits PatchDiff
a Relation Reference TypeEdit
-> Relation Reference TypeEdit -> Relation Reference TypeEdit
forall a. Semigroup a => a -> a -> a
<> PatchDiff -> Relation Reference TypeEdit
_removedTypeEdits PatchDiff
b
      }

instance Monoid PatchDiff where
  mempty :: PatchDiff
mempty = Relation Reference TermEdit
-> Relation Reference TypeEdit
-> Relation Reference TermEdit
-> Relation Reference TypeEdit
-> PatchDiff
PatchDiff Relation Reference TermEdit
forall a. Monoid a => a
mempty Relation Reference TypeEdit
forall a. Monoid a => a
mempty Relation Reference TermEdit
forall a. Monoid a => a
mempty Relation Reference TypeEdit
forall a. Monoid a => a
mempty