predicate-transformers (empty) → 0.1.0.0
raw patch · 4 files changed
+158/−0 lines, 4 filesdep +adjunctionsdep +basedep +lens
Dependencies added: adjunctions, base, lens
Files
- CHANGELOG.md +5/−0
- LICENSE +30/−0
- predicate-transformers.cabal +28/−0
- src/PredicateTransformers.hs +95/−0
+ CHANGELOG.md view
@@ -0,0 +1,5 @@+# Revision history for predicate-transformers++## 0.1.0.0 -- 2019-10-05++* First version. Released on an unsuspecting world.
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright (c) 2019, Edmund Noble++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++ * Redistributions of source code must retain the above copyright+ notice, this list of conditions and the following disclaimer.++ * Redistributions in binary form must reproduce the above+ copyright notice, this list of conditions and the following+ disclaimer in the documentation and/or other materials provided+ with the distribution.++ * Neither the name of Edmund Noble nor the names of other+ contributors may be used to endorse or promote products derived+ from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ predicate-transformers.cabal view
@@ -0,0 +1,28 @@+cabal-version: 2.4++name: predicate-transformers+version: 0.1.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.+-- bug-reports:+license: BSD-3-Clause+license-file: LICENSE+author: Edmund Noble+maintainer: edmundnoble@gmail.com+-- copyright:+category: Data+extra-source-files: CHANGELOG.md+source-repository head+ type: git+ location: https://gitlab.com/edmundnoble/predicate-transformers++library+ exposed-modules: PredicateTransformers+ -- other-modules:+ -- other-extensions:+ build-depends: base ^>=4.11 || ^>=4.12 || ^>=4.13+ ,lens ^>=4.17 || ^>=4.18+ ,adjunctions ^>=4.2 || ^>=4.3 || ^>=4.4+ hs-source-dirs: src+ default-language: Haskell2010
+ src/PredicateTransformers.hs view
@@ -0,0 +1,95 @@+-- | 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@.+-- They act as a sort of compositional "matcher language".+-- Composing these predicate transformers is meant to be analogous to composing optics+-- and there are utilities for using predicate transformers with (`lens`-style) optics.+module PredicateTransformers where++import Prelude hiding (all)+import Control.Lens hiding (index, zoom)+import Data.Foldable(toList)+import Data.Functor.Rep(Representable(..))+import Debug.Trace++-- |A convenient alias for predicates.+type Pred a = a -> Bool++-- |Predicate transformers form a category where composition is ordinary function+-- composition.+-- Multiple are already provided by the standard library,+-- for instance `Data.Foldable.all` and `Data.Foldable.any`.+type PT a b = Pred a -> Pred b++-- |Functor from Hask^op to PT.+function :: (b -> a) -> PT a b+function = flip (.)++-- |Operate on the target of a prism, or fail.+match :: APrism s t a b -> PT a s+match p pred s = either (const False) pred (matching p s)++-- |Operate on the target of a getter.+getter :: Getting a s a -> PT a s+getter g = function (view g)++-- |Invert a predicate.+nay :: PT a a+nay = (not .)++-- |Operate on the `Just` branch of a `Maybe`, or fail.+just :: PT a (Maybe a)+just = match _Just++-- |Operate on the `Left` branch of an `Either`, or fail.+left :: PT e (Either e a)+left = match _Left++-- |Operate on the `Right` branch of an `Either`, or fail.+right :: PT a (Either e a)+right = match _Right++-- |Operate on the last value in a list, or fail if it's not present.+endingWith :: PT a [a]+endingWith _ [] = False+endingWith p xs = p $ last xs++-- |Operate on the first value in a list, or fail if it's not present.+startingWith :: PT a [a]+startingWith p (x:_) = p x+startingWith _ [] = False++-- |Require that a list has a single element, and operate on that element.+only :: PT a [a]+only p [x] = p x+only _ _ = False++-- |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.+dist :: [Pred a] -> Pred [a]+dist (p:ps) (x:xs) = p x && dist ps xs+dist [] [] = True+dist _ _ = False++-- |Given a functor-full of predicates, and a functor-full of values, ensure that the structures+-- of the two functors match and apply all of the predicates to all of the values.+-- Generalized version of `dist`.+distF ::+ (Eq (f ()), Functor f, Foldable f) =>+ f (Pred a) -> Pred (f a)+distF preds values =+ (() <$ preds) == (() <$ values) &&+ dist (toList preds) (toList values)++-- |Given a representable functor-full of predicates, and a functor-full of values,+-- yield a representable functor-full of booleans. Similar to `distF`.+distRep :: Representable f =>+ f (a -> Bool) -> f a -> f Bool+distRep pr fa = tabulate (\r -> index pr r $ index fa r)++-- |Sugar for tupling.+(==>) :: a -> b -> (a, b)+(==>) = (,)++-- |Prints the input of a predicate, for debugging.+traced :: Show a => PT a a+traced = function traceShowId