Maintainer | darcs-devel@darcs.net |
---|---|

Stability | experimental |

Portability | portable |

Safe Haskell | None |

Language | Haskell2010 |

## Synopsis

- class CleanMerge p where
- cleanMerge :: (p :\/: p) wX wY -> Maybe ((p :/\: p) wX wY)

- class CleanMerge p => Merge p where
- selfMerger :: Merge p => MergeFn p p
- swapMerger :: MergeFn p q -> MergeFn q p
- mergerIdFL :: MergeFn p q -> MergeFn p (FL q)
- mergerFLId :: MergeFn p q -> MergeFn (FL p) q
- mergerFLFL :: MergeFn p q -> MergeFn (FL p) (FL q)
- cleanMergeFL :: CleanMerge p => PartialMergeFn p (FL p)
- mergeFL :: Merge p => (p :\/: FL p) wX wY -> (FL p :/\: p) wX wY
- swapMerge :: Merge p => (p :\/: p) wX wY -> (p :/\: p) wX wY
- swapCleanMerge :: CleanMerge p => (p :\/: p) wX wY -> Maybe ((p :/\: p) wX wY)
- mergeList :: CleanMerge p => [Sealed (FL p wX)] -> Either (Sealed (FL p wX), Sealed (FL p wX)) (Sealed (FL p wX))
- prop_mergeSymmetric :: (Eq2 p, Merge p) => (p :\/: p) wX wY -> Bool
- prop_mergeCommute :: (Commute p, Eq2 p, Merge p) => (p :\/: p) wX wY -> Bool

# Classes

class CleanMerge p where Source #

Class of patches that can, possibly, be merged cleanly, that is, without conflict.

Every patch type can be made an instance of `CleanMerge`

in a trivial way by
defining

, which vacuously conforms to all
required laws.`cleanMerge`

_ = `Nothing`

Instances should obey the following laws:

*symmetry*cleanMerge (p :\/: q) == Just (q' :/\: p') <=> cleanMerge (q :\/: p) == Just (p' :/\: q')

If an instance

exists, then we also require`Commute`

p

*merge-commute*cleanMerge (p :\/: q) == Just (q' :/\: p') ==> commute (p :> q') == Just (q :> p')

that is, the two branches of a clean merge commute to each other.

If an instance

exists, then we also require`Invert`

p

*square-merge*cleanMerge (p :\/: q) == Just (q' :/\: p') => cleanMerge (invert p :\/: q') == Just (q :/\: invert p')

Here is a picture that explains why we call this

*square-merge*:A---p--->X A<--p^---X | | | | | | | | q q' => q q' | | | | v v v v Y---p'-->B Y<--p'^--B

## Instances

class CleanMerge p => Merge p where Source #

Patches that can always be merged, even if they conflict.

Instances should obey the following laws:

*symmetry*merge (p :\/: q) == q' :/\: p' <=> merge (q :\/: p) == p' :/\: q'

*merge-commute*merge (p :\/: q) == q' :/\: p' ==> commute (p :> q') == Just (q :> p')

that is, the two branches of a merge commute to each other.

*extension*cleanMerge (p :\/: q) == Just (q' :/\: p') => merge (p :\/: q) == q' :/\: p'

that is,

`merge`

is an extension of`cleanMerge`

.

## Instances

Merge p => Merge (FL p) Source # | |

PrimPatch prim => Merge (RepoPatchV1 prim) Source # | |

Defined in Darcs.Patch.V1.Commute merge :: (RepoPatchV1 prim :\/: RepoPatchV1 prim) wX wY -> (RepoPatchV1 prim :/\: RepoPatchV1 prim) wX wY Source # | |

PrimPatch prim => Merge (RepoPatchV2 prim) Source # | |

Defined in Darcs.Patch.V2.RepoPatch merge :: (RepoPatchV2 prim :\/: RepoPatchV2 prim) wX wY -> (RepoPatchV2 prim :/\: RepoPatchV2 prim) wX wY Source # | |

Merge p => Merge (Named p) Source # | |

(PatchId p ~ PatchInfo, Merge p) => Merge (PatchInfoAndG rt p) Source # | |

Defined in Darcs.Patch.PatchInfoAnd merge :: (PatchInfoAndG rt p :\/: PatchInfoAndG rt p) wX wY -> (PatchInfoAndG rt p :/\: PatchInfoAndG rt p) wX wY Source # | |

(SignedId name, StorableId name, PrimPatch prim) => Merge (RepoPatchV3 name prim) Source # | |

Defined in Darcs.Patch.V3.Core merge :: (RepoPatchV3 name prim :\/: RepoPatchV3 name prim) wX wY -> (RepoPatchV3 name prim :/\: RepoPatchV3 name prim) wX wY Source # |

# Functions

swapMerger :: MergeFn p q -> MergeFn q p Source #

Swap the two patches, apply an arbitrary merge function, then swap again.

mergerIdFL :: MergeFn p q -> MergeFn p (FL q) Source #

Lift a merge function over `p :/: q`

to a merge function over `p :/: FL q`

mergerFLId :: MergeFn p q -> MergeFn (FL p) q Source #

Lift a merge function over `p :/: q`

to a merge function over `FL p :/: q`

mergerFLFL :: MergeFn p q -> MergeFn (FL p) (FL q) Source #

Lift a merge function over `p :/: q`

to a merge function over `FL p :/: FL q`

cleanMergeFL :: CleanMerge p => PartialMergeFn p (FL p) Source #

Cleanly merge a single patch with an `FL`

of patches.

swapMerge :: Merge p => (p :\/: p) wX wY -> (p :/\: p) wX wY Source #

Swap the two patches, `merge`

, then swap again. Used to exploit
`prop_mergeSymmetric`

when defining `merge`

.

swapCleanMerge :: CleanMerge p => (p :\/: p) wX wY -> Maybe ((p :/\: p) wX wY) Source #

Swap the two patches, `cleanMerge`

, then swap again. Used to exploit
`prop_cleanMergeSymmetric`

when defining `cleanMerge`

.

mergeList :: CleanMerge p => [Sealed (FL p wX)] -> Either (Sealed (FL p wX), Sealed (FL p wX)) (Sealed (FL p wX)) Source #

Combine a list of patch sequences, all starting at the same state, into a single sequence that also starts at the same state, using cleanMerge. If the merge fails, we return the two sequences that could not be merged so we can issue more detailed error messages.