Empty (empty) → 0.1.0.0
raw patch · 5 files changed
+150/−0 lines, 5 filesdep +basedep +containerssetup-changed
Dependencies added: base, containers
Files
- ChangeLog.md +5/−0
- Empty.cabal +25/−0
- LICENSE +30/−0
- Setup.hs +2/−0
- src/Control/Empty.hs +88/−0
+ ChangeLog.md view
@@ -0,0 +1,5 @@+# Revision history for Empty++## 0.1.0.0 -- YYYY-mm-dd++* First version. Released on an unsuspecting world.
+ Empty.cabal view
@@ -0,0 +1,25 @@+-- Initial Empty.cabal generated by cabal init. For further documentation,+-- see http://haskell.org/cabal/users-guide/++name: Empty+version: 0.1.0.0+synopsis: A type class for empty containers+description: HasEmpty f has a member empty of type forall a. f a+license: BSD3+license-file: LICENSE+author: Isaac Shapira+maintainer: fresheyeball@gmail.com+-- copyright:+category: Control+build-type: Simple+extra-source-files: ChangeLog.md+cabal-version: >=1.10++library+ exposed-modules: Control.Empty+ -- other-modules:+ -- other-extensions:+ build-depends: base >=4.9 && <4.10+ , containers+ hs-source-dirs: src+ default-language: Haskell2010
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright (c) 2017, Isaac Shapira++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 Isaac Shapira 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.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ src/Control/Empty.hs view
@@ -0,0 +1,88 @@+{-# LANGUAGE DefaultSignatures #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE TypeOperators #-}++module Control.Empty where++import qualified Control.Applicative as AP+import Data.Functor.Compose+import qualified Data.Functor.Product as FP+import qualified Data.IntMap as IntMap+import qualified Data.Map as Map+import Data.Proxy+import Data.Semigroup+import qualified Data.Sequence as Seq+import qualified Data.Set as Set+import GHC.Conc+import Text.ParserCombinators.ReadP+import Text.ParserCombinators.ReadPrec++{-| The class of type of @* -> *@ which may be empty.+ There is only one law for HasEmpty and its enforced by the type.+ The law is that there exists a value in type f for which a is fully generic.+ This alone is often enough to uniquely determine the value for a given,+ data type.++ Additional laws for HasEmpty work backwards, @empty@ has a relationships+ with other classes. So if @f@ is a member of one of these classes,+ the following should hold.++ [/Functor identity/]++ @g \<$\> empty = empty@++ [/Applicative annililation left/]++ @x \<*\> empty = empty@++ [/Applicative annililation right/]++ @empty \<*\> x = empty@++ [/Monad identity/]++ @empty >>= f = empty@++ [/Alternative empty/]++ @empty = Alternative.empty@++ [/MonadPlus mzero/]++ @empty = mzero@++ [/Foldable identity/]++ @foldr f x empty = empty@++-}+class HasEmpty f where+ empty :: forall a. f a+ default empty :: AP.Alternative f => f a+ empty = AP.empty++instance HasEmpty Maybe+instance HasEmpty []+instance HasEmpty IO+instance HasEmpty STM+instance HasEmpty Proxy+instance HasEmpty Option+instance HasEmpty ReadP+instance HasEmpty ReadPrec++instance (AP.Alternative f, AP.Alternative g) => HasEmpty (FP.Product f g)+instance (AP.Alternative f, AP.Applicative g) => HasEmpty (Compose f g)++instance HasEmpty IntMap.IntMap where empty = mempty+instance HasEmpty (Map.Map k) where empty = Map.empty+instance HasEmpty Seq.Seq where empty = Seq.empty+instance HasEmpty Set.Set where empty = Set.empty+++coerce :: HasEmpty f => a -> f b+coerce _ = empty+++isEmpty :: (HasEmpty f, Eq (f a)) => f a -> Bool+isEmpty = (== empty)