packages feed

IsNull (empty) → 0.3.0.0

raw patch · 7 files changed

+308/−0 lines, 7 filesdep +HUnitdep +QuickCheckdep +basesetup-changed

Dependencies added: HUnit, QuickCheck, base, base-compat, bytestring, containers, hspec, quickcheck-instances, system-filepath, text, unordered-containers, vector

Files

+ IsNull.cabal view
@@ -0,0 +1,58 @@+name:                IsNull+version:             0.3.0.0+synopsis:            A typeclass to determine if a given value is null.+description:         A typeclass to determine if a given foldable type+                     (or other) is empty ~ null ~ invalid.+                     The definition is intentionally vague, to cover types+                     from Either to Text and Sets.+homepage:            https://github.com/jcristovao/IsNull+license:             BSD3+license-file:        LICENSE+author:              João Cristóvão+maintainer:          jmacristovao@gmail.com+category:            Data+build-type:          Simple++extra-source-files: README.md++-- Constraint on the version of Cabal needed to build this package.+cabal-version:       >=1.16++library+  other-modules:       Data.IsNull.Internal+  exposed-modules:     Data.IsNull+  build-depends:       base             >= 4.5    && < 4.8+                     , base-compat      >= 0.5    && < 0.6+                     , containers       >= 0.5    && < 0.6+                     , text             >= 0.11.3 && < 1.3+                     , bytestring       >= 0.10.0 && < 1.0++  hs-source-dirs:      src+  ghc-options:         -Wall+  default-language:    Haskell2010+  +-- the test suite checks for most (modern) applicable types+-- found on Cabal. Exceptions: utf8-string, ListLike, IxSet++test-suite test+  type:               exitcode-stdio-1.0+  main-is:            main.hs+  hs-source-dirs:     test,src+  build-depends:       base             >= 4.5    && < 4.8+                     , base-compat      >= 0.5    && < 0.6+                     , containers       >= 0.5    && < 0.6+                     , text             >= 0.11.3 && < 1.3+                     , unordered-containers >= 0.2.3+                     , vector           >= 0.10.0.1+                     , text             >= 0.11.3.1+                     , bytestring       >= 0.10.0.2+                     , system-filepath  >= 0.4.6+                     , QuickCheck       >= 2.6+                     , quickcheck-instances >= 0.3.5 +                     , HUnit            >= 1.2.5.2+                     , hspec            >= 1.7.2+  default-language: Haskell2010++source-repository head+  type:     git+  location: https://github.com/jcristovao/IsNull
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright (c) 2014, João Cristóvão++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 João Cristóvão 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.
+ README.md view
@@ -0,0 +1,61 @@+IsNull+======++A typeclass to determine if a given container is null.++Strongly inspired by +[mono-traversable](https://hackage.haskell.org/package/mono-traversable), +but with a simpler goal: supporting IsNull and nested IsNull operations.++Supported functions:++```+isNull :: a -> Bool++notNull :: a -> Bool++-- | Nested isNull+isNullN :: (Foldable f) => f a -> Bool++-- | Monadic isNull+isNullM :: Monad m => m a -> m Bool++-- | Monadic Nested isNull+isNullNM :: (Monad m, Foldable f) => m (f a) -> m Bool+++-- | Alternative <|> operator does not always operate as choice,+-- at least not in an intuitive way (for example with lists).+-- This one does:+<\> :: a -> a -> a+```++The N stands for (non-recursive) nested, such that:++```++isNullN (Just "abc") == False+isNullN (Just ""   ) == True+isNullN (Nothing   ) == True++```++While the ```isNull``` function is equivalent to ```(==) mempty```+for most of the instances, not all ```Foldable```s are monoids,+and not all monoids ```mempty``` means null:++* ```Either``` is an example of a ```Foldable``` which is not a+  ```Monoid```, but where it makes sense to consider a ```Left``` as+  an 'Null' value. While this is not strictly true, the ```Left```+  option does carries a value, we take the more liberal approach:+  Empty ~ Null ~ Invalid Value.+  If you need proper type reasoning, you should not be using this+  package, just regular pattern matching instead.++* ```Product``` ```Monoid``` instance is ```1```. Hardly qualifies as an+  ```Empty``` or ```Null``` value. For this reason no default implementation+  is provided for the ```Monoid``` class. It's up to you to use+  ```(==) mempty``` instead.+++Bugs, suggestions and comments are most welcomed!
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ src/Data/IsNull.hs view
@@ -0,0 +1,53 @@+{-# LANGUAGE CPP #-}+{-# LANGUAGE FlexibleInstances  #-}+{-# LANGUAGE FlexibleContexts   #-}+{-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE IncoherentInstances  #-}+{-# OPTIONS_GHC -fno-warn-orphans #-}++{- |+Module:      IsNull+Description: A typeclass to determine if a given value is null.+Copyright:   João Cristóvão, 2014+License:     BSD3+Maintainer:  jmacristovao@gmail.com++A typeclass to determine if a given value is null.++Strongly inspired by+<https://hackage.haskell.org/package/mono-traversable mono-traversable>+but with a simpler goal: supporting IsNull and nested IsNull operations.++While the @'isNull'@ function is equivalent to @(==) mempty@ for most of+the instances, not all @'Foldable'@s are monoids,+and not all monoids @'mempty'@ means null:++* @'Either'@ is an example of a @Foldable@ which is not a+  @'Monoid'@, but where it makes sense to consider a @'Left'@ as+  an 'Null' value. While this is not strictly true, the @'Left'@+  option does carries a value, we take the more liberal approach:+  Empty ~ Null ~ Invalid Value.+  If you need proper type reasoning, you should not be using this+  package, just regular pattern matching instead.++* @'Product'@ @'Monoid'@ instance is @1@. Hardly qualifies as an+  @Empty@ or @Null@ value. For this reason no default implementation+  is provided for the @'Monoid'@ class. It's up to you to use+  @(==) mempty@ instead.++The main use case for this package are boolean conditions,+namely the @if@ @then@ @else@ construct.++Bugs, suggestions and comments are most welcomed!++<https://github.com/jcristovao/IsNull>++-}+module Data.IsNull (+    IsNull(..)+) where+++import Data.IsNull.Internal++
+ src/Data/IsNull/Internal.hs view
@@ -0,0 +1,102 @@+{-# LANGUAGE FlexibleInstances    #-}+{-# LANGUAGE FlexibleContexts     #-}+{-# LANGUAGE OverloadedStrings    #-}+{-# OPTIONS_GHC -fno-warn-orphans #-}++module Data.IsNull.Internal where++import qualified Data.Foldable.Compat as F+import qualified Data.Text            as T+import qualified Data.Text.Lazy       as LT+import qualified Data.ByteString      as BS+import qualified Data.ByteString.Lazy as LBS+import qualified Data.IntSet          as IS+import Control.Monad (liftM)+++class IsNull a where+  -- | isNull ~ isEmpty ~ isInvalid?+  --+  -- >>> isNull (Left 5)+  -- True+  --+  -- >>> isNull ("abc" :: T.Text)+  -- False+  --+  -- >>> isNull [""] -- see isNullN+  -- False+  isNull:: a -> Bool++  -- | Typing causes arthritis. Alias for @'isNull'@.+  isN :: a -> Bool+  isN = isNull++  -- | the logical negation of @'isNull'@+  notNull :: a -> Bool+  notNull = not . isNull++  -- | Nested isNull+  --+  -- >>> isNullN (Just "abc")+  -- False+  --+  -- >>> isNullN (Just "")+  -- True+  --+  -- >>> isNullN (Nothing :: Maybe String)+  -- True+  isNullN :: F.Foldable f => f a -> Bool+  isNullN = F.all isNull++  -- | Nested isNotNull+  notNullN :: F.Foldable f => f a -> Bool+  notNullN = not . isNullN++  -- | Monadic isNull+  --+  -- >>> isNullM [""]+  -- [True]+  isNullM :: Monad m => m a -> m Bool+  isNullM = liftM isNull++  -- | Monadic Nested isNull+  isNullNM :: (Monad m, F.Foldable f) => m (f a) -> m Bool+  isNullNM = liftM isNullN++  -- | @'Alternative'@'s @'<|>'@ operator does not always operate as choice,+  -- at least not in an intuitive way (for example with lists).+  -- This one does:+  --+  -- >>> [2,3] <\> [4,5]+  -- [2,3]+  --+  -- >>> [] <\> [4,5]+  -- [4,5]+  --+  -- >>> [] <\> []+  -- []+  (<\>) :: a -> a -> a+  (<\>) a b = if isNull a then b else a+  infixl 3 <\>++instance IsNull Bool where+  isNull = not++instance IsNull T.Text where+  isNull = T.null++instance IsNull LT.Text where+  isNull = LT.null++instance IsNull BS.ByteString where+  isNull = BS.null++instance IsNull LBS.ByteString where+  isNull = LBS.null++instance IsNull IS.IntSet where+  isNull = IS.null++instance F.Foldable f => IsNull (f a) where+  isNull = F.foldr (\_ _ -> False) True+
+ test/main.hs view
@@ -0,0 +1,2 @@+{-# OPTIONS_GHC -F -pgmF hspec-discover #-}+