predicate-transformers 0.12.0.0 → 0.13.0.0
raw patch · 2 files changed
+34/−34 lines, 2 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
- PredicateTransformers: (!) :: (b -> a) -> (a -> c) -> b -> c
- PredicateTransformers: (?) :: (a -> b) -> a -> b
- PredicateTransformers: infixl 9 ?
- PredicateTransformers: infixr 8 !
- PredicateTransformers: type PT p a b = (a -> p) -> (b -> p)
+ PredicateTransformers: pt :: (a -> b) -> PT p b a
+ PredicateTransformers: type Pred p a = HasCallStack => a -> p
- PredicateTransformers: PredicateFailed :: PredicateFailed
+ PredicateTransformers: PredicateFailed :: !CallStack -> PredicateFailed
- PredicateTransformers: allTrue :: (Predicatory p, Foldable f) => f (a -> p) -> a -> p
+ PredicateTransformers: allTrue :: (Predicatory p, Foldable f) => f (Pred p a) -> Pred p a
- PredicateTransformers: also :: Predicatory a => a -> a -> a
+ PredicateTransformers: also :: (Predicatory a, HasCallStack) => a -> a -> a
- PredicateTransformers: dist :: (Predicatory p, Eq (f ()), Functor f, Foldable f) => f (a -> p) -> f a -> p
+ PredicateTransformers: dist :: (Predicatory p, Eq (f ()), Functor f, Foldable f) => f (Pred p a) -> Pred p (f a)
- PredicateTransformers: distRep :: Representable f => f (a -> p) -> f a -> f p
+ PredicateTransformers: distRep :: Representable f => f (Pred p a) -> f a -> f p
- PredicateTransformers: equals :: (Predicatory p, Eq a) => a -> a -> p
+ PredicateTransformers: equals :: (Predicatory p, Eq a) => a -> Pred p a
- PredicateTransformers: forced :: (Predicatory p, NFData a) => a -> p
+ PredicateTransformers: forced :: (Predicatory p, NFData a) => Pred p a
- PredicateTransformers: list :: Predicatory p => [a -> p] -> [a] -> p
+ PredicateTransformers: list :: Predicatory p => [Pred p a] -> [a] -> p
- PredicateTransformers: otherHand :: Predicatory a => a -> a -> a
+ PredicateTransformers: otherHand :: (Predicatory a, HasCallStack) => a -> a -> a
- PredicateTransformers: pair :: Predicatory p => (a -> p) -> (b -> p) -> (a, b) -> p
+ PredicateTransformers: pair :: Predicatory p => Pred p a -> Pred p b -> Pred p (a, b)
- PredicateTransformers: satAll :: Predicatory p => [a -> p] -> a -> p
+ PredicateTransformers: satAll :: Predicatory p => [Pred p a] -> Pred p a
- PredicateTransformers: something :: Predicatory p => a -> p
+ PredicateTransformers: something :: Predicatory p => Pred p a
- PredicateTransformers: stop :: Predicatory a => a
+ PredicateTransformers: stop :: (Predicatory a, HasCallStack) => a
- PredicateTransformers: type Pred a = a -> Bool
+ PredicateTransformers: type PT p a b = HasCallStack => Pred p a -> Pred p b
Files
- predicate-transformers.cabal +1/−1
- src/PredicateTransformers.hs +33/−33
predicate-transformers.cabal view
@@ -1,7 +1,7 @@ cabal-version: 2.4 name: predicate-transformers-version: 0.12.0.0+version: 0.13.0.0 synopsis: A library for writing predicates and transformations over predicates in Haskell description: This package provides ways to write predicates such that they compose nicely and are easy to debug.
src/PredicateTransformers.hs view
@@ -5,6 +5,7 @@ {-# LANGUAGE PatternSynonyms #-} {-# LANGUAGE ScopedTypeVariables #-} {-# OPTIONS_GHC -fexpose-all-unfoldings #-}+{-# LANGUAGE ImpredicativeTypes #-} -- | This library is based on the notion of a predicate transformer, the below -- type @PT a b@, which is a function from @a@ to predicates on @b@.@@ -34,6 +35,7 @@ import Control.Concurrent (myThreadId, throwTo) import Control.Exception (SomeAsyncException) import GHC.Conc (pseq)+import GHC.Stack -- | Class of possible predicate results. -- This is mostly a lattice with `otherHand` as disjunction, `also` as conjunction, `stop` as the falsy@@ -41,16 +43,16 @@ -- Note that test failure messages are not really the domain of this library. -- It's the author's hope that they can be mostly replaced by `traceFail`. class Predicatory a where- otherHand :: a -> a -> a- also :: a -> a -> a- stop :: a+ otherHand :: HasCallStack => a -> a -> a+ also :: HasCallStack => a -> a -> a+ stop :: HasCallStack => a continue :: a {-# MINIMAL otherHand, also, stop, continue #-} instance Predicatory a => Predicatory (e -> a) where (f `otherHand` f') e = f e `otherHand` f' e (f `also` f') e = f e `also` f' e- stop = \_ -> stop+ stop = withFrozenCallStack $ \_ -> stop continue = \_ -> continue infixr 3 `also`@@ -65,10 +67,15 @@ assess f act = \e -> assess (f e) act -- | The exception thrown by predicates of type `IO ()` by default. Other IOExceptions will work fine.-data PredicateFailed = PredicateFailed- deriving (Show, Typeable)+data PredicateFailed = PredicateFailed !CallStack+ deriving (Typeable)+instance Show PredicateFailed where+ show = displayException -instance Exception PredicateFailed+instance Exception PredicateFailed where+ displayException (PredicateFailed cs) =+ "Predicate failed.\n" <>+ prettyCallStack cs instance Predicatory Bool where otherHand = (||)@@ -92,7 +99,7 @@ , Handler $ \(_ex :: SomeException) -> y ] also = (>>)- stop = throwIO PredicateFailed+ stop = throwIO (PredicateFailed callStack) continue = return () instance Exceptional (IO ()) where@@ -108,13 +115,13 @@ ] -- | A convenient alias for predicates.-type Pred a = a -> Bool+type Pred p a = HasCallStack => a -> p -- | Predicate transformers form a category where composition is ordinary function composition. -- Forms a category with `.` and `id`. -- Multiple are already provided by the standard library, -- for instance `Data.Foldable.all` and `Data.Foldable.any`.-type PT p a b = (a -> p) -> (b -> p)+type PT p a b = HasCallStack => Pred p a -> Pred p b -- | Operate on the `Just` branch of a `Maybe`, or fail. just :: Predicatory p => PT p a (Maybe a)@@ -139,7 +146,7 @@ startingWith _ (toList -> []) = stop -- | Require that a @Fold@ has a single element, and operate on that element.-soleElementOf :: Predicatory p => Fold s a -> PT p a s+soleElementOf :: (Predicatory p) => Fold s a -> PT p a s soleElementOf f p (toListOf f -> [x]) = p x soleElementOf _ _ _ = stop @@ -153,7 +160,7 @@ -- | Given a list of predicates and a list of values, ensure that each predicate holds for each respective value. -- Fails if the two lists have different lengths.-list :: Predicatory p => [a -> p] -> [a] -> p+list :: Predicatory p => [Pred p a] -> [a] -> p list (p : ps) (x : xs) = p x `also` list ps xs list [] [] = continue list _ _ = stop@@ -163,9 +170,8 @@ -- Generalized version of `list`. dist :: (Predicatory p, Eq (f ()), Functor f, Foldable f) =>- f (a -> p) ->- f a ->- p+ f (Pred p a) ->+ Pred p (f a) dist preds values = bool stop continue ((() <$ preds) == (() <$ values)) `also` list (toList preds) (toList values)@@ -174,13 +180,13 @@ -- yield a representable functor-full of booleans. Similar to `dist`. distRep :: Representable f =>- f (a -> p) ->+ f (Pred p a) -> f a -> f p distRep pr fa = tabulate (\r -> index pr r $ index fa r) -- | Test all predicates against one value.-allTrue :: (Predicatory p, Foldable f) => f (a -> p) -> a -> p+allTrue :: (Predicatory p, Foldable f) => f (Pred p a) -> Pred p a allTrue ps a = foldr (\p r -> p a `also` r) continue ps -- | Check that a predicate is true for all values behind a generalized getter@@ -194,18 +200,12 @@ pattern a :=> b = (a, b) -- | A pair of predicates, made into a predicate on pairs.-pair :: Predicatory p => (a -> p) -> (b -> p) -> (a, b) -> p+pair :: Predicatory p => Pred p a -> Pred p b -> Pred p (a, b) pair f s (a, b) = f a `also` s b --- | Flipped function composition; @f !@ for a function @f@ is a predicate transformer.-(!) :: (b -> a) -> (a -> c) -> b -> c-(!) = flip (.)-infixr 8 !---- | Higher precedence @$@, to work well with '!'.-(?) :: (a -> b) -> a -> b-(?) = ($)-infixl 9 ?+-- | Flipped function composition; @pt f@ for a function @f@ is a predicate transformer.+pt :: (a -> b) -> PT p b a+pt f p = p . f -- | Prints the input of a predicate, for debugging. traced :: Show a => (a -> String) -> PT c a a@@ -227,18 +227,18 @@ assess (p a) $ traceIO (s a) -- | Predicate which always succeeds.-something :: Predicatory p => a -> p+something :: Predicatory p => Pred p a something = const continue -- | Predicate which triggers full evaluation of its input and succeeds. -- Useful for testing that an exception isn't thrown.-forced :: (Predicatory p, NFData a) => a -> p+forced :: (Predicatory p, NFData a) => Pred p a forced a = force a `seq` continue -- | Predicate on equality.-equals :: (Predicatory p, Eq a) => a -> a -> p-equals a a' = bool stop continue (a == a')+equals :: (Predicatory p, Eq a) => a -> Pred p a+equals a a' = bool (stop a') continue (a == a') -- | Check that all of the input predicates are satisfied.-satAll :: Predicatory p => [a -> p] -> a -> p-satAll = foldr also continue+satAll :: Predicatory p => [Pred p a] -> Pred p a+satAll xs a = foldr (\p xs -> p a `also` xs) continue xs