packages feed

data-flagset (empty) → 1.0.0.0

raw patch · 4 files changed

+267/−0 lines, 4 filesdep +basesetup-changed

Dependencies added: base

Files

+ Data/FlagSet.hs view
@@ -0,0 +1,173 @@+{-# LANGUAGE DeriveDataTypeable #-}+-- | +-- = Introduction+-- This module provides a data type for a set of flags. Flags are stored+-- efficiently as bits of an unsigned integer.+--+-- This module is meant to be imported qualified:+--+-- @+-- import qualified Data.FlagSet as FlagSet+-- import Data.FlagSet (FlagSet)+-- @+--+-- The API is basically the same as that of "Data.Set" from the @containers@ package.+--+-- The functions `fromList` and `member` also have aliases that can be used +-- unqualified:+-- +-- @+-- import Data.FlagSet (flags, hasFlag)+-- @+--+-- = Examples+--+-- @+-- import qualified Data.FlagSet as FlagSet+-- import Data.FlagSet (FlagSet, flags, hasFlag)+--+-- data WeekDay = Monday | Tuesday | Wednesday | Thursday | Friday | Saturday | Sunday+--      deriving (Eq, Show, Enum, Bounded)+--+-- workDays = flags [Monday .. Friday]+-- weekEndDays = flags [Saturday, Sunday]+-- allDays = FlagSet.full+--+-- worksOnTheWeekEnd :: FlagSet WeekDay -> Bool+-- worksOnTheWeekEnd = not . FlagSet.null . FlagSet.intersection weekEndDays+--+-- worksOnSunday :: FlagSet WeekDay -> Bool+-- worksOnSunday = hasFlag Sunday+--+-- workDayPay :: Rational+-- workDayPay = ...+-- weekEndDayPay :: Rational+-- weekEndDayPay = ...+--+-- pay :: FlagSet WeekDay -> Rational+-- pay daysWorking = workDayPay * countDays workDays + weekEndDayPay * countDays weekEndDays+--     where+--         countDays = fromIntegral . FlagSet.size . FlagSet.intersection daysWorking+-- @+module Data.FlagSet+    ( -- * Types+      FlagSet+      -- * Construction+    , fromList, flags, empty, singleton, full+      -- * Modification+    , insert, delete, union, unions, difference, intersection+      -- * Tests+    , member, hasFlag, null+      -- * Other+    , toList, size+    ) where++import Data.Data (Data)+import Data.Typeable (Typeable)+import Data.Word (Word32)+import Data.Bits (setBit, testBit, clearBit, (.|.), (.&.), complement, popCount)+import Data.Monoid (Monoid(..))+import Prelude hiding (null)++-- | A set of flags.+--+--   For most functions operating on flag sets, there must be an `Enum`+--   instance for @a@. Some functions also require `Bounded`.+--+--   You must ensure that `fromEnum` only returns values in the range+--   @[0 .. 31]@, otherwise an error can occur.+-- +--   In the `Monoid` instance, `mempty` is `empty` and `mappend`/`<>` is `union`.+newtype FlagSet a = MkFlagSet Word32 deriving (Data, Typeable)++instance Eq (FlagSet a) where+    MkFlagSet x == MkFlagSet y = x == y++instance Ord (FlagSet a) where+    compare (MkFlagSet x) (MkFlagSet y) = compare x y++instance (Show a, Enum a) => Show (FlagSet a) where+    showsPrec p fs = showParen (p > 10) $+        showString "fromList " . shows (toList fs)++instance Monoid (FlagSet a) where+    mempty = empty+    mappend = union++-- | Alias for `fromList` that can be imported unqualified.+flags :: Enum a => [a] -> FlagSet a+flags = fromList++-- | Alias for `member` that can be imported unqualified.+hasFlag :: Enum a => a -> FlagSet a -> Bool+hasFlag = member++-- | Create a flag set from a list of flags. Input list can contain duplicates.+fromList :: Enum a => [a] -> FlagSet a+fromList vals = go vals 0+    where+        go [] acc = MkFlagSet acc+        go (v:vs) acc = withBit "fromList" v (go vs . setBit acc)++-- | Test whether a flag set contains a value.+member :: Enum a => a -> FlagSet a -> Bool+member v (MkFlagSet bits) = withBit "member" v (testBit bits)++withBit :: Enum a => String -> a -> (Int -> b) -> b+withBit fun v cont =+    let+        n = fromEnum v+    in+        if n < 0 || n > 31+            then error $ "Data.FlagSet." ++ fun ++ ": enum out of range"+            else cont n++-- | Convert a flag set to a list of values. The values will be ordered+--   according to the order defined by `fromEnum` and there will not be any+--   duplicates.+toList :: Enum a => FlagSet a -> [a]+toList (MkFlagSet bits) = map toEnum $ filter (testBit bits) [0 .. 31]++-- | The empty flag set.+empty :: FlagSet a+empty = MkFlagSet 0++-- | A flag set containing a single value.+singleton :: Enum a => a -> FlagSet a+singleton v = withBit "singleton" v (MkFlagSet . setBit 0)++-- | The union of two flag sets.+union :: FlagSet a -> FlagSet a -> FlagSet a+union (MkFlagSet x) (MkFlagSet y) = MkFlagSet (x .|. y)++-- | The union of multiple flag sets.+unions :: [FlagSet a] -> FlagSet a+unions = foldl union empty++-- | The difference of two flag sets.+difference :: FlagSet a -> FlagSet a -> FlagSet a+difference (MkFlagSet x) (MkFlagSet y) = MkFlagSet (x .&. complement y)++-- | The intersection of two flag sets.+intersection :: FlagSet a -> FlagSet a -> FlagSet a+intersection (MkFlagSet x) (MkFlagSet y) = MkFlagSet (x .&. y)++-- | The flag set that contains every value.+full :: (Enum a, Bounded a) => FlagSet a+full = fromList [minBound .. maxBound]++-- | Insert a value into a flag set.+insert :: Enum a => a -> FlagSet a -> FlagSet a+insert v (MkFlagSet bits) = withBit "insert" v (MkFlagSet . setBit bits)++-- | Remove a value from a flag set.+delete :: Enum a => a -> FlagSet a -> FlagSet a+delete v (MkFlagSet bits) = withBit "delete" v (MkFlagSet . clearBit bits)++-- | Test whether a flag set is empty.+null :: FlagSet a -> Bool+null = (== empty)++-- | The number of values in a flag set.+size :: FlagSet a -> Int+size (MkFlagSet bits) = popCount bits
+ LICENSE view
@@ -0,0 +1,20 @@+Copyright (c) 2015 Tobias Brandt++Permission is hereby granted, free of charge, to any person obtaining+a copy of this software and associated documentation files (the+"Software"), to deal in the Software without restriction, including+without limitation the rights to use, copy, modify, merge, publish,+distribute, sublicense, and/or sell copies of the Software, and to+permit persons to whom the Software is furnished to do so, subject to+the following conditions:++The above copyright notice and this permission notice shall be included+in all copies or substantial portions of the Software.++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ data-flagset.cabal view
@@ -0,0 +1,72 @@+-- Initial data-flagset.cabal generated by cabal init.  For further +-- documentation, see http://haskell.org/cabal/users-guide/++-- The name of the package.+name:                data-flagset++-- The package version.  See the Haskell package versioning policy (PVP) +-- for standards guiding when and how versions should be incremented.+-- http://www.haskell.org/haskellwiki/Package_versioning_policy+-- PVP summary:      +-+------- breaking API changes+--                   | | +----- non-breaking API additions+--                   | | | +--- code changes with no API change+version:             1.0.0.0++-- A short (one-line) description of the package.+synopsis:            An efficient data type for sets of flags++-- A longer description of the package.+description:         This package provides a data type for representing a set of+                     enum flags with an API similar to that of Data.Set from+                     the containers package.++-- The license under which the package is released.+license:             MIT++-- The file containing the license text.+license-file:        LICENSE++-- The package author(s).+author:              Tobias Brandt++-- An email address to which users can send suggestions, bug reports, and +-- patches.+maintainer:          tob.brandt@gmail.com++-- A copyright notice.+copyright:           Copyright 2015, Tobias Brandt++category:            Data++build-type:          Simple++-- Extra files to be distributed with the package, such as examples or a +-- README.+-- extra-source-files:  ++-- Constraint on the version of Cabal needed to build this package.+cabal-version:       >=1.10+++library+  -- Modules exported by the library.+  exposed-modules:   Data.FlagSet+  +  -- Modules included in this library but not exported.+  -- other-modules:       +  +  -- LANGUAGE extensions used by modules in this package.+  -- other-extensions:    +  +  -- Other library packages from which modules are imported.+  build-depends:       base >=4.5 && <4.9+  +  -- Directories containing source files.+  -- hs-source-dirs:      +  +  -- Base language which the package is written in.+  default-language:    Haskell2010+  +source-repository head+    type: git+    location: git://github.com/TobBrandt/data-flagset.git