rg 1.2.0.0 → 1.3.0.0
raw patch · 4 files changed
+73/−21 lines, 4 files
Files
- ChangeLog.md +2/−3
- rg.cabal +2/−2
- src/Data/Rg.hs +57/−16
- test/test.hs +12/−0
ChangeLog.md view
@@ -1,7 +1,6 @@ # Changelog for rg -## Unreleased changes- * 1.0.0.0: first release * 1.1.0.0: add RgText, BE derivation- - 1.2.0.0: first public release+ * 1.2.0.0: first public release+ * 1.3.0.0: add rgCoreMethods
rg.cabal view
@@ -4,10 +4,10 @@ -- -- see: https://github.com/sol/hpack ----- hash: 527175fcfe23d40d0a87e869a4613c10ea692ae5c67e26c181bae7d7f71687ee+-- hash: 3cabf1da9ca011c22c7a2edbd99264013666a9ece5fb53cf4229c97323160ee0 name: rg-version: 1.2.0.0+version: 1.3.0.0 synopsis: A dynamic/unbounded alternative to Bounded Enum description: Please see the README on GitHub at <https://github.com/cdornan/rg#readme> category: Types
src/Data/Rg.hs view
@@ -1,9 +1,12 @@ {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE ScopedTypeVariables #-} module Data.Rg ( Rg(..)+ , RgCoreMethods+ , rgCoreMethodsBE , RgText(..) , BE(..) , Range@@ -13,6 +16,7 @@ ) where import Data.Array+import Data.Coerce import qualified Data.HashMap.Strict as HM import Data.Maybe import Data.Possibly@@ -25,46 +29,60 @@ -- can be dynamically determined from each value in the type (see 'sizeRg') class Rg rg where -- | the number of values in the enumeration; sizeRg sz > 0- sizeRg :: rg -> Int+ sizeRg :: rg -> Int+ sizeRg = _rcm_sizeRg rgCoreMethods -- | the nth item in the enumeration (first is 0)- toRg :: rg -> Int -> Maybe rg+ toRg :: rg -> Int -> Maybe rg+ toRg = _rcm_toRg rgCoreMethods -- | place in the enumation (first is 0)- fromRg :: rg -> Int+ fromRg :: rg -> Int+ fromRg = _rcm_fromRg rgCoreMethods + -- | an alternative way of specifying sizeRg, toRg and fromRg+ rgCoreMethods :: RgCoreMethods rg+ rgCoreMethods =+ RgCoreMethods+ { _rcm_sizeRg = sizeRg+ , _rcm_toRg = toRg+ , _rcm_fromRg = fromRg+ }++ {-# MINIMAL sizeRg, toRg, fromRg | rgCoreMethods #-}+ -- | first item in the enumeration- minRg :: rg -> rg- minRg = fromMaybe oops . flip toRg 0+ minRg :: rg -> rg+ minRg = fromMaybe oops . flip toRg 0 where- oops = error "minRg: no minimum value in range"+ oops = error "minRg: no minimum value in range" -- | last item in the enumeration- maxRg :: rg -> rg- maxRg rg = fromMaybe oops $ toRg rg n+ maxRg :: rg -> rg+ maxRg rg = fromMaybe oops $ toRg rg n where- n = sizeRg rg - 1- oops = error "maxRg: no maximum value in range"+ n = sizeRg rg - 1+ oops = error "maxRg: no maximum value in range" -- | next item in the enumeration (Nothing if already last)- succRg :: rg -> Maybe rg+ succRg :: rg -> Maybe rg succRg rg = toRg rg $ fromRg rg + 1 -- | previous item in the enumeration (Nothing if already first)- predRg :: rg -> Maybe rg+ predRg :: rg -> Maybe rg predRg rg = toRg rg $ fromRg rg - 1 -- | list given items in the enumeration- allListRg :: rg -> [rg]+ allListRg :: rg -> [rg] allListRg rg = listRg rg [0..] -- | list given items in the enumeration, stopping as soon as an index is -- out of range- listRg :: rg -> [Int] -> [rg]+ listRg :: rg -> [Int] -> [rg] listRg rg is = catMaybes $ takeWhile isJust [ toRg rg i | i<-is ] -- | list given items in the enumeration as a 'V.Vector'- allVectorRg :: rg -> [rg]+ allVectorRg :: rg -> [rg] allVectorRg rg = listRg rg [0..] -- | list the items in the enumeration as a 'V.Vector', stopping as soon as an@@ -73,7 +91,31 @@ vectorRg rg is = V.fromList $ listRg rg is + -------------------------------------------------------------------------------+-- RgCoreMethods+-------------------------------------------------------------------------------++-- | dynamically encapsulates the core 'Rg' methods+data RgCoreMethods rg =+ RgCoreMethods+ { _rcm_sizeRg :: rg -> Int+ , _rcm_toRg :: rg -> Int -> Maybe rg+ , _rcm_fromRg :: rg -> Int+ }++-- | if you want to create an 'Rg' from a 'Bounded' 'Enum' you can bind+-- 'rgCoreMethods' to this function+rgCoreMethodsBE :: forall rg . (Bounded rg, Enum rg) => RgCoreMethods rg+rgCoreMethodsBE =+ RgCoreMethods+ { _rcm_sizeRg = coerce (sizeRg :: BE rg -> Int)+ , _rcm_toRg = coerce (toRg :: BE rg -> Int -> Maybe (BE rg))+ , _rcm_fromRg = coerce (fromRg :: BE rg -> Int)+ }+++------------------------------------------------------------------------------- -- class RgText ------------------------------------------------------------------------------- @@ -154,7 +196,6 @@ -- hashmap_t ------------------------------------------------------------------------------- --- | 'T.Text' 'HM.HashMap' based on 'renderEnumText' representation hashmap_t :: RgText e => e -> HM.HashMap T.Text e hashmap_t x = HM.fromList [ (fmt $ build c,c)
test/test.hs view
@@ -38,6 +38,16 @@ , testCase "fromRg False" $ 0 @=? fromRg (BE False) , testCase "fromRg True" $ 1 @=? fromRg (BE True ) ]+ , testGroup "rgCoreMethodsBE"+ [ testCase "sizeRg True" $ 2 @=? sizeRg True+ , testCase "sizeRg False" $ 2 @=? sizeRg False+ , testCase "toRg 0" $ Just False @=? toRg False 0+ , testCase "toRg 1" $ Just True @=? toRg False 1+ , testCase "toRg 3" $ Nothing @=? toRg False 2+ , testCase "allListRg" $ [False,True] @=? allListRg False+ , testCase "fromRg False" $ 0 @=? fromRg False+ , testCase "fromRg True" $ 1 @=? fromRg True+ ] , testGroup "RgText" [ testCase "TRUE" $ Right (BE True ) @=? parseRgText (BE False) "TRUE" , testCase "FALSE" $ Right (BE False) @=? parseRgText (BE True ) "FALSE"@@ -52,6 +62,8 @@ msg = "parseRgText: enumeration not recognised: \"false\"" instance RgText (BE Bool)++instance Rg Bool where rgCoreMethods = rgCoreMethodsBE instance Buildable (BE Bool) where build (BE True) = "TRUE"