{-# LANGUAGE CPP #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeFamilies #-}
module Data.Patch.Class where
import Data.Functor.Identity
import Data.Kind (Type)
import Data.Maybe
#if !MIN_VERSION_base(4,11,0)
import Data.Semigroup (Semigroup(..))
#endif
import Data.Proxy
class Patch p where
type PatchTarget p :: Type
apply :: p -> PatchTarget p -> Maybe (PatchTarget p)
applyAlways :: Patch p => p -> PatchTarget p -> PatchTarget p
applyAlways :: p -> PatchTarget p -> PatchTarget p
applyAlways p
p PatchTarget p
t = PatchTarget p -> Maybe (PatchTarget p) -> PatchTarget p
forall a. a -> Maybe a -> a
fromMaybe PatchTarget p
t (Maybe (PatchTarget p) -> PatchTarget p)
-> Maybe (PatchTarget p) -> PatchTarget p
forall a b. (a -> b) -> a -> b
$ p -> PatchTarget p -> Maybe (PatchTarget p)
forall p. Patch p => p -> PatchTarget p -> Maybe (PatchTarget p)
apply p
p PatchTarget p
t
instance Patch (Identity a) where
type PatchTarget (Identity a) = a
apply :: Identity a
-> PatchTarget (Identity a) -> Maybe (PatchTarget (Identity a))
apply (Identity a
a) PatchTarget (Identity a)
_ = a -> Maybe a
forall a. a -> Maybe a
Just a
a
instance forall (a :: Type). Patch (Proxy a) where
type PatchTarget (Proxy a) = a
apply :: Proxy a -> PatchTarget (Proxy a) -> Maybe (PatchTarget (Proxy a))
apply ~Proxy a
Proxy PatchTarget (Proxy a)
_ = Maybe (PatchTarget (Proxy a))
forall a. Maybe a
Nothing
composePatchFunctions :: (Patch p, Semigroup p) => (PatchTarget p -> p) -> (PatchTarget p -> p) -> PatchTarget p -> p
composePatchFunctions :: (PatchTarget p -> p) -> (PatchTarget p -> p) -> PatchTarget p -> p
composePatchFunctions PatchTarget p -> p
g PatchTarget p -> p
f PatchTarget p
a =
let fp :: p
fp = PatchTarget p -> p
f PatchTarget p
a
in PatchTarget p -> p
g (p -> PatchTarget p -> PatchTarget p
forall p. Patch p => p -> PatchTarget p -> PatchTarget p
applyAlways p
fp PatchTarget p
a) p -> p -> p
forall a. Semigroup a => a -> a -> a
<> p
fp