on develop help sign in
Add `composePatchFunctions`
commit06ba50db10cc37ef100366a556208b46991def9f authorRyan Trinkle <ryan.trinkle@gmail.com> dateSun 26 Aug 2018, 13:46 (8 years ago) parent826d24d
1 file changed+12
src/Reflex/Patch/Class.hs+12
src/Reflex/Patch/Class.hs+12
@@ -4,8 +4,12 @@ module Reflex.Patch.Class where
44
55import Control.Monad.Identity
66import Data.Maybe
7+import Data.Semigroup
78
89-- | A 'Patch' type represents a kind of change made to a datastructure.
10+--
11+-- If an instance of 'Patch' is also an instance of 'Semigroup', it should obey
12+-- the law that @applyAlways (f <> g) == applyAlways f . applyAlways g@.
913class Patch p where
1014 type PatchTarget p :: *
1115 -- | Apply the patch @p a@ to the value @a@. If no change is needed, return
@@ -20,3 +24,11 @@ applyAlways p t = fromMaybe t $ apply p t
2024instance Patch (Identity a) where
2125 type PatchTarget (Identity a) = a
2226 apply (Identity a) _ = Just a
27+
28+-- | Like '(.)', but composes functions that return patches rather than
29+-- functions that return new values. The Semigroup instance for patches must
30+-- apply patches right-to-left, like '(.)'.
31+composePatchFunctions :: (Patch p, Semigroup p) => (PatchTarget p -> p) -> (PatchTarget p -> p) -> PatchTarget p -> p
32+composePatchFunctions g f a =
33+ let fp = f a
34+ in g (applyAlways fp a) <> fp