@@ -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