kure 2.2.0 → 2.4.0
raw patch · 3 files changed
+38/−16 lines, 3 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
- Language.KURE.Combinators: condM :: Monad m => m Bool -> m a -> m a -> m a
+ Language.KURE.Combinators: accepterR :: (CategoryCatch ~>, ArrowApply ~>) => (a ~> Bool) -> String -> (a ~> a)
+ Language.KURE.Combinators: constant :: Arrow ~> => b -> (a ~> b)
+ Language.KURE.Combinators: ifM :: Monad m => m Bool -> m a -> m a -> m a
+ Language.KURE.Combinators: prefixFailMsg :: MonadCatch m => String -> m a -> m a
+ Language.KURE.Combinators: unlessM :: Monad m => m Bool -> m a -> m a
- Language.KURE.Combinators: acceptR :: (CategoryCatch ~>, ArrowApply ~>) => (a -> Bool) -> (a ~> a)
+ Language.KURE.Combinators: acceptR :: (CategoryCatch ~>, ArrowApply ~>) => (a -> Bool) -> String -> (a ~> a)
Files
- Language/KURE/Combinators.hs +34/−12
- Language/KURE/Walker.hs +3/−3
- kure.cabal +1/−1
Language/KURE/Combinators.hs view
@@ -25,18 +25,21 @@ , notM , modFailMsg , setFailMsg+ , prefixFailMsg , withPatFailMsg -- ** Conditionals , guardMsg , guardM- , condM+ , ifM , whenM+ , unlessM -- * Arrow Combinators -- ** Categories with a Catch , CategoryCatch(..) , (<+) , readerT , acceptR+ , accepterR , tryR , attemptR , changedR@@ -55,6 +58,7 @@ , fork , forkFirst , forkSecond+ , constant ) where import Prelude hiding (id , (.), catch)@@ -107,7 +111,7 @@ -- | Fail if the 'Monad' succeeds; succeed with @()@ if it fails. notM :: MonadCatch m => m a -> m ()-notM ma = condM (testM ma) (fail "notM of success") (return ())+notM ma = ifM (testM ma) (fail "notM of success") (return ()) -- | Modify the error message of a failing monadic computation. -- Successful computations are unaffected.@@ -119,6 +123,11 @@ setFailMsg :: MonadCatch m => String -> m a -> m a setFailMsg msg = modFailMsg (const msg) +-- | Add a prefix to the error message of a failing monadic computation.+-- Successful computations are unaffected.+prefixFailMsg :: MonadCatch m => String -> m a -> m a+prefixFailMsg msg = modFailMsg (msg ++)+ -- | Use the given error message whenever a monadic pattern match failure occurs. withPatFailMsg :: MonadCatch m => String -> m a -> m a withPatFailMsg msg = modFailMsg (\ e -> if "Pattern match failure" `isPrefixOf` e then msg else e)@@ -131,17 +140,21 @@ -- | As 'guardMsg', but with a default error message. guardM :: Monad m => Bool -> m ()-guardM b = guardMsg b "guard failed"+guardM b = guardMsg b "guardM failed" --- | if-then-else lifted over a 'Monad'.-condM :: Monad m => m Bool -> m a -> m a -> m a-condM mb m1 m2 = do b <- mb- if b then m1 else m2+-- | if-then-else lifted over a monadic predicate.+ifM :: Monad m => m Bool -> m a -> m a -> m a+ifM mb m1 m2 = do b <- mb+ if b then m1 else m2 --- | if-then lifted over a 'Monad'.+-- | If the monadic predicate holds then perform the monadic action, else fail. whenM :: Monad m => m Bool -> m a -> m a-whenM mb ma = condM mb ma (fail "condition False")+whenM mb ma = ifM mb ma (fail "whenM: condition False") +-- | If the monadic predicate holds then fail, else perform the monadic action.+unlessM :: Monad m => m Bool -> m a -> m a+unlessM mb ma = ifM mb (fail "unlessM: condition True") ma+ ------------------------------------------------------------------------------------------ -- | 'Category's with failure and catching.@@ -166,9 +179,14 @@ readerT f = (f &&& id) ^>> app -- | Look at the argument to an 'Arrow', and choose to be either the identity arrow or a failure.-acceptR :: (CategoryCatch (~>), ArrowApply (~>)) => (a -> Bool) -> (a ~> a)-acceptR p = readerT $ \ a -> if p a then id else failT "acceptR: predicate failed"+acceptR :: (CategoryCatch (~>), ArrowApply (~>)) => (a -> Bool) -> String -> (a ~> a)+acceptR p msg = readerT $ \ a -> if p a then id else failT msg +-- | Look at the argument to an 'Arrow', and choose to be either the identity arrow or a failure.+-- This is a generalisation of 'acceptR' to any 'Arrow'.+accepterR :: (CategoryCatch (~>), ArrowApply (~>)) => (a ~> Bool) -> String -> (a ~> a)+accepterR t msg = forkFirst t >>> readerT (\ (b,a) -> if b then constant a else failT msg)+ -- | Catch a failing 'CategoryCatch', making it into an identity. tryR :: CategoryCatch (~>) => (a ~> a) -> (a ~> a) tryR r = r <+ id@@ -180,7 +198,7 @@ -- | Makes an 'Arrow' fail if the result value equals the argument value. changedR :: (CategoryCatch (~>), ArrowApply (~>), Eq a) => (a ~> a) -> (a ~> a)-changedR r = readerT (\ a -> r >>> acceptR (/=a))+changedR r = readerT (\ a -> r >>> acceptR (/=a) "changedR: value is unchanged") -- | Repeat a 'CategoryCatch' until it fails, then return the result before the failure. -- Requires at least the first attempt to succeed.@@ -236,5 +254,9 @@ -- | Tag the result of an 'Arrow' with its argument. forkSecond :: Arrow (~>) => (a ~> b) -> (a ~> (a , b)) forkSecond sf = fork >>> second sf++-- | An arrow with a constant result.+constant :: Arrow (~>) => b -> (a ~> b)+constant b = arr (const b) -------------------------------------------------------------------------------
Language/KURE/Walker.hs view
@@ -349,12 +349,12 @@ -- | Find the 'Path's to every 'Node' that satisfies the predicate. pathsToT :: (PathContext c, Walker c m a, a ~ Generic a) => (Generic a -> Bool) -> Translate c m (Generic a) [Path]-pathsToT q = collectT (acceptR q >>> absPathT) >>= mapM abs2pathT+pathsToT q = collectT (acceptR q "pathsToT" >>> absPathT) >>= mapM abs2pathT -- | Find the 'Path' to the first 'Node' that satisfies the predicate (in a pre-order traversal). onePathToT :: (PathContext c, Walker c m a, a ~ Generic a) => (Generic a -> Bool) -> Translate c m (Generic a) Path onePathToT q = setFailMsg "No matching nodes found." $- onetdT (acceptR q >>> absPathT) >>= abs2pathT+ onetdT (acceptR q "pathsToT" >>> absPathT) >>= abs2pathT -- | Find the 'Path' to the first descendent 'Node' that satisfies the predicate (in a pre-order traversal). oneNonEmptyPathToT :: (PathContext c, Walker c m a, a ~ Generic a) => (Generic a -> Bool) -> Translate c m (Generic a) Path@@ -364,7 +364,7 @@ -- | Find the 'Path's to every 'Node' that satisfies the predicate, ignoring 'Node's below successes. prunePathsToT :: (PathContext c, Walker c m a, a ~ Generic a) => (Generic a -> Bool) -> Translate c m (Generic a) [Path]-prunePathsToT q = collectPruneT (acceptR q >>> absPathT) >>= mapM abs2pathT+prunePathsToT q = collectPruneT (acceptR q "pathsToT" >>> absPathT) >>= mapM abs2pathT -- local function used by uniquePathToT and uniquePrunePathToT
kure.cabal view
@@ -1,5 +1,5 @@ Name: kure-Version: 2.2.0+Version: 2.4.0 Synopsis: Combinators for Strategic Programming Description: The Kansas University Rewrite Engine (KURE) is a DSL for strategic rewriting. KURE shares concepts with Stratego, but unlike Stratego, KURE is strongly typed.