4
4
{-# LANGUAGE FlexibleInstances #-}
5
5
{-# LANGUAGE LambdaCase #-}
6
6
{-# LANGUAGE StandaloneDeriving #-}
7
+ {-# LANGUAGE TypeFamilies #-}
7
8
{-# LANGUAGE UndecidableInstances #-}
8
9
9
10
module Data.Patch.PatchOrReplacement where
@@ -14,10 +15,16 @@ import Data.Semigroup (Semigroup (..))
14
15
#endif
15
16
import GHC.Generics
16
17
17
- -- | Like SemiMap/PartialMap but for anything patchable
18
+ -- | Either a patch or a replacement value.
19
+ --
20
+ -- A good patch type will describe small changes very efficiently, but
21
+ -- that often comes at the cost of describing large change rather
22
+ -- inefficiently. 'PatchOrReplacement' can be used as an escape hatch:
23
+ -- when the change as a patch would be too big, just provide a new value
24
+ -- to replace the old one with instead.
18
25
data PatchOrReplacement p
19
26
= PatchOrReplacement_Patch p
20
- | PatchOrReplacement_Complete (PatchTarget p )
27
+ | PatchOrReplacement_Replacement (PatchTarget p )
21
28
deriving (Generic )
22
29
23
30
deriving instance (Eq p , Eq (PatchTarget p )) => Eq (PatchOrReplacement p )
@@ -27,9 +34,17 @@ deriving instance (Read p, Read (PatchTarget p)) => Read (PatchOrReplacement p)
27
34
28
35
completePatchOrReplacement :: PatchOrReplacement p -> Maybe (PatchTarget p )
29
36
completePatchOrReplacement = \ case
30
- PatchOrReplacement_Complete t -> Just t
37
+ PatchOrReplacement_Replacement t -> Just t
31
38
PatchOrReplacement_Patch _ -> Nothing
32
39
40
+ -- | 'PatchOrReplacement p' is a patch when we can apply the patch or
41
+ -- replace the old value with the new replacement value.
42
+ instance Patch p => Patch (PatchOrReplacement p ) where
43
+ type PatchTarget (PatchOrReplacement p ) = PatchTarget p
44
+ apply = \ case
45
+ PatchOrReplacement_Patch p -> apply p
46
+ PatchOrReplacement_Replacement v -> \ _ -> Just v
47
+
33
48
instance ( Monoid p
34
49
#if !MIN_VERSION_base(4,11,0)
35
50
, Semigroup p
@@ -42,5 +57,5 @@ instance ( Monoid p
42
57
instance (Semigroup p , Patch p ) => Semigroup (PatchOrReplacement p ) where
43
58
(<>) = curry $ \ case
44
59
(PatchOrReplacement_Patch a, PatchOrReplacement_Patch b) -> PatchOrReplacement_Patch $ a <> b
45
- (PatchOrReplacement_Patch a, PatchOrReplacement_Complete b) -> PatchOrReplacement_Complete $ applyAlways a b
46
- (PatchOrReplacement_Complete a, _) -> PatchOrReplacement_Complete a
60
+ (PatchOrReplacement_Patch a, PatchOrReplacement_Replacement b) -> PatchOrReplacement_Replacement $ applyAlways a b
61
+ (PatchOrReplacement_Replacement a, _) -> PatchOrReplacement_Replacement a
0 commit comments