{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE KindSignatures #-}
module Data.JoinSemilattice.Class.Merge where
import Data.Hashable (Hashable)
import Data.JoinSemilattice.Defined (Defined (..))
import Data.JoinSemilattice.Intersect (Intersect (..))
import qualified Data.JoinSemilattice.Intersect as Intersect
import Data.Kind (Type)
data Result (x :: Type)
= Unchanged
| Changed x
| Failure
deriving stock (Result x -> Result x -> Bool
(Result x -> Result x -> Bool)
-> (Result x -> Result x -> Bool) -> Eq (Result x)
forall x. Eq x => Result x -> Result x -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Result x -> Result x -> Bool
$c/= :: forall x. Eq x => Result x -> Result x -> Bool
== :: Result x -> Result x -> Bool
$c== :: forall x. Eq x => Result x -> Result x -> Bool
Eq, a -> Result b -> Result a
(a -> b) -> Result a -> Result b
(forall a b. (a -> b) -> Result a -> Result b)
-> (forall a b. a -> Result b -> Result a) -> Functor Result
forall a b. a -> Result b -> Result a
forall a b. (a -> b) -> Result a -> Result b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: a -> Result b -> Result a
$c<$ :: forall a b. a -> Result b -> Result a
fmap :: (a -> b) -> Result a -> Result b
$cfmap :: forall a b. (a -> b) -> Result a -> Result b
Functor, Eq (Result x)
Eq (Result x)
-> (Result x -> Result x -> Ordering)
-> (Result x -> Result x -> Bool)
-> (Result x -> Result x -> Bool)
-> (Result x -> Result x -> Bool)
-> (Result x -> Result x -> Bool)
-> (Result x -> Result x -> Result x)
-> (Result x -> Result x -> Result x)
-> Ord (Result x)
Result x -> Result x -> Bool
Result x -> Result x -> Ordering
Result x -> Result x -> Result x
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
forall x. Ord x => Eq (Result x)
forall x. Ord x => Result x -> Result x -> Bool
forall x. Ord x => Result x -> Result x -> Ordering
forall x. Ord x => Result x -> Result x -> Result x
min :: Result x -> Result x -> Result x
$cmin :: forall x. Ord x => Result x -> Result x -> Result x
max :: Result x -> Result x -> Result x
$cmax :: forall x. Ord x => Result x -> Result x -> Result x
>= :: Result x -> Result x -> Bool
$c>= :: forall x. Ord x => Result x -> Result x -> Bool
> :: Result x -> Result x -> Bool
$c> :: forall x. Ord x => Result x -> Result x -> Bool
<= :: Result x -> Result x -> Bool
$c<= :: forall x. Ord x => Result x -> Result x -> Bool
< :: Result x -> Result x -> Bool
$c< :: forall x. Ord x => Result x -> Result x -> Bool
compare :: Result x -> Result x -> Ordering
$ccompare :: forall x. Ord x => Result x -> Result x -> Ordering
$cp1Ord :: forall x. Ord x => Eq (Result x)
Ord, Int -> Result x -> ShowS
[Result x] -> ShowS
Result x -> String
(Int -> Result x -> ShowS)
-> (Result x -> String) -> ([Result x] -> ShowS) -> Show (Result x)
forall x. Show x => Int -> Result x -> ShowS
forall x. Show x => [Result x] -> ShowS
forall x. Show x => Result x -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Result x] -> ShowS
$cshowList :: forall x. Show x => [Result x] -> ShowS
show :: Result x -> String
$cshow :: forall x. Show x => Result x -> String
showsPrec :: Int -> Result x -> ShowS
$cshowsPrec :: forall x. Show x => Int -> Result x -> ShowS
Show)
instance Semigroup x => Semigroup (Result x) where
Changed x
x <> :: Result x -> Result x -> Result x
<> Changed x
y = x -> Result x
forall x. x -> Result x
Changed (x
x x -> x -> x
forall a. Semigroup a => a -> a -> a
<> x
y)
Result x
Failure <> Result x
_ = Result x
forall x. Result x
Failure
Result x
_ <> Result x
Failure = Result x
forall x. Result x
Failure
Result x
Unchanged <> Result x
y = Result x
y
Result x
x <> Result x
Unchanged = Result x
x
instance Semigroup x => Monoid (Result x) where
mempty :: Result x
mempty = Result x
forall x. Result x
Unchanged
instance Applicative Result where
pure :: a -> Result a
pure = a -> Result a
forall x. x -> Result x
Changed
Result (a -> b)
Failure <*> :: Result (a -> b) -> Result a -> Result b
<*> Result a
_ = Result b
forall x. Result x
Failure
Result (a -> b)
_ <*> Result a
Failure = Result b
forall x. Result x
Failure
Result (a -> b)
Unchanged <*> Result a
_ = Result b
forall x. Result x
Unchanged
Result (a -> b)
_ <*> Result a
Unchanged = Result b
forall x. Result x
Unchanged
Changed a -> b
f <*> Changed a
x = b -> Result b
forall x. x -> Result x
Changed (a -> b
f a
x)
class Monoid x => Merge (x :: Type) where
(<<-) :: x -> x -> Result x
instance Eq content => Merge (Defined content) where
Defined content
Conflict <<- :: Defined content -> Defined content -> Result (Defined content)
<<- Defined content
_ = Result (Defined content)
forall x. Result x
Failure
Defined content
_ <<- Defined content
Conflict = Result (Defined content)
forall x. Result x
Failure
Defined content
_ <<- Defined content
Unknown = Result (Defined content)
forall x. Result x
Unchanged
Defined content
Unknown <<- Defined content
that = Defined content -> Result (Defined content)
forall x. x -> Result x
Changed Defined content
that
Exactly content
this <<- Exactly content
that
| content
this content -> content -> Bool
forall a. Eq a => a -> a -> Bool
== content
that = Result (Defined content)
forall x. Result x
Unchanged
| Bool
otherwise = Result (Defined content)
forall x. Result x
Failure
instance (Bounded x, Enum x, Ord x, Hashable x)
=> Merge (Intersect x) where
Intersect x
before <<- :: Intersect x -> Intersect x -> Result (Intersect x)
<<- Intersect x
news = case Intersect x
before Intersect x -> Intersect x -> Intersect x
forall a. Semigroup a => a -> a -> a
<> Intersect x
news of
Intersect x
joined | Intersect x -> Int
forall x. Intersectable x => Intersect x -> Int
Intersect.size Intersect x
joined Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
1 -> Result (Intersect x)
forall x. Result x
Failure
| Intersect x -> Int
forall x. Intersectable x => Intersect x -> Int
Intersect.size Intersect x
joined Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Intersect x -> Int
forall x. Intersectable x => Intersect x -> Int
Intersect.size Intersect x
before -> Intersect x -> Result (Intersect x)
forall x. x -> Result x
Changed Intersect x
joined
| Bool
otherwise -> Result (Intersect x)
forall x. Result x
Unchanged