-
Notifications
You must be signed in to change notification settings - Fork 0
/
Patch.hs
61 lines (47 loc) · 1.23 KB
/
Patch.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
module Patch
( Patch (..)
, empty
, singleton
, append
, apply
, transform
)
where
import Edit (Edit)
import qualified Edit
import Data.Text (Text)
import Data.Vector (Vector)
import qualified Data.Vector as Vector
newtype Patch = Patch
{ edits :: Vector Edit
}
deriving (Show)
{- Note Patch properties
let (a', b') = transform (a, b)
in apply (a `append` b') doc == apply (b `append` a') doc
-}
instance Monoid Patch where
mempty = empty
mappend = append
empty :: Patch
empty = Patch Vector.empty
singleton :: Edit -> Patch
singleton edit = Patch (Vector.singleton edit)
append :: Patch -> Patch -> Patch
append p1 p2 = Patch (edits p1 Vector.++ edits p2)
apply :: Patch -> Text -> Text
apply (Patch p) txt = Vector.foldl' step txt p
where
step txt' edit = Edit.apply edit txt'
transform :: Patch -> Patch -> (Patch, Patch)
transform (Patch a) b =
let step (a', b') a1 =
let (a1', b'') = transformEdit a1 b'
in (append a' (singleton a1'), b'')
in Vector.foldl' step (empty, b) a
transformEdit :: Edit -> Patch -> (Edit, Patch)
transformEdit a (Patch b) =
let step (a', b') b1 =
let (a'', b1') = Edit.transform a' b1
in (a'', append b' (singleton b1'))
in Vector.foldl' step (a, empty) b