patch: Infrastructure for writing patches which act on other types.

[ bsd3, frp, library ] [ Propose Tags ]

In this library, a patch is something which can be applied, analogous to a function, and which distinguishes returning the argument it was provided from returning something else.


[Skip to Readme]
Versions [faq] 0.0.0.0, 0.0.0.1, 0.0.1.0, 0.0.2.0, 0.0.3.0, 0.0.3.1 (info)
Change log ChangeLog.md
Dependencies base (>=4.9 && <4.14), constraints-extras (==0.3.*), containers (==0.6.*), dependent-map (==0.3.*), dependent-sum (==0.6.*), lens (>=4.7 && <5), monoidal-containers (==0.4.0.0 || ==0.6.*), semialign (>=1 && <1.2), semigroupoids (>=4.0 && <6), these (>=0.4 && <0.9 || >=1 && <1.1), transformers (>=0.5.6.0 && <0.6), witherable (>=0.3 && <0.3.2) [details]
License BSD-3-Clause
Author Ryan Trinkle
Maintainer maintainer@obsidian.systems
Category FRP
Home page https://obsidian.systems
Bug tracker https://github.com/reflex-frp/patch/issues
Source repo head: git clone https://github.com/reflex-frp/patch
Uploaded by JohnEricson at 2020-02-06T03:16:38Z
Distributions NixOS:0.0.3.1
Downloads 1412 total (72 in the last 30 days)
Rating (no votes yet) [estimated by Bayesian average]
Your Rating
  • λ
  • λ
  • λ
Status Hackage Matrix CI
Docs available [build log]
Last success reported on 2020-02-06 [all 1 reports]

Modules

[Index] [Quick Jump]

Flags

NameDescriptionDefaultType
split-these

Use split these/semialign packages

EnabledAutomatic

Use -f <flag> to enable a flag, or -f -<flag> to disable that flag. More info

Downloads

Maintainer's Corner

For package maintainers and hackage trustees


Readme for patch-0.0.3.1

[back to package description]

Patch

Infrastructure for writing patches which act on other types.

A Patch type represents a kind of change made to a datastructure.

class Patch p where
  type PatchTarget p :: *
  -- | Apply the patch p a to the value a.  If no change is needed, return
  -- 'Nothing'.
  apply :: p -> PatchTarget p -> Maybe (PatchTarget p)

Patching Maps

For example, Data.Patch.Map defines the PatchMap type which can be used to patch Maps. A PatchMap represents updates to a Map that can insert, remove, or replace items in the Map. In this example, the Map is the PatchTarget and the PatchMap is the Patch. Keep in mind that there are many other possible Patches that can be applied to a Map (i.e., Map can be the PatchTarget for many different Patch instances).

PatchMap is defined as:

newtype PatchMap k v = PatchMap { unPatchMap :: Map k (Maybe v) }

The Maybe around the value is used to represent insertion/updates or deletion of the element at a given key.

Its Patch instance begins with:

instance Ord k => Patch (PatchMap k v) where
  type PatchTarget (PatchMap k v) = Map k v
  ...

When a PatchMap is applied to its PatchTarget, the following changes can occur:

  • If the key is present in the Patch and the PatchTarget...

    • And the Patch value at that key is Nothing: delete that key from the PatchTarget.

    • And the Patch value at that key is Just x: update the value at that key in the PatchTarget to x.

  • If the key is present in the Patch and not present in the PatchTarget...

    • And the Patch value at that key is Nothing: do nothing because we're trying to delete a key that doesn't exist in the target in the first place.

    • And the Patch value at that key is Just x: insert the key and the value x into the PatchTarget

  • If the key is not present in the Patch but present in the PatchTarget: do nothing.

There are, of course, more complicated ways of patching maps involving, for example, moving values from one key to another. You can find the code for that in Data.Patch.PatchMapWithMove. Note that the PatchTarget type associated with the PatchMapWithMove patch instance is still Map k v!