nats 1 → 1.1
raw patch · 4 files changed
+118/−8 lines, 4 filesdep +binarydep +template-haskell
Dependencies added: binary, template-haskell
Files
- .travis.yml +10/−0
- CHANGELOG.markdown +4/−0
- nats.cabal +33/−4
- src/Numeric/Natural.hs +71/−4
.travis.yml view
@@ -3,15 +3,25 @@ # See also https://github.com/hvr/multi-ghc-travis for more information env: - GHCVER=7.0.4 CABALVER=1.16+ - GHCVER=7.0.4 CABALVER=1.16 OPTS=-f-hashable+ - GHCVER=7.0.4 CABALVER=1.16 OPTS=-f-template-haskell+ - GHCVER=7.0.4 CABALVER=1.16 OPTS=-f-binary+ - GHCVER=7.0.4 CABALVER=1.16 OPTS="-f-hashable -f-template-haskell"+ - GHCVER=7.0.4 CABALVER=1.16 OPTS="-f-hashable -f-binary"+ - GHCVER=7.0.4 CABALVER=1.16 OPTS="-f-binary -f-template-haskell" # we have to use CABALVER=1.16 for GHC<7.6 as well, as there's # no package for earlier cabal versions in the PPA - GHCVER=7.4.2 CABALVER=1.16 - GHCVER=7.6.3 CABALVER=1.16 OPTS="--constraint=hashable>=1.2" - GHCVER=7.6.3 CABALVER=1.16 OPTS="--constraint=hashable<1.2" - GHCVER=7.6.3 CABALVER=1.16 OPTS=-f-hashable+ - GHCVER=7.6.3 CABALVER=1.16 OPTS=-f-template-haskell+ - GHCVER=7.6.3 CABALVER=1.16 OPTS=-f-binary - GHCVER=7.8.3 CABALVER=1.18 OPTS="--constraint=hashable>=1.2" - GHCVER=7.8.3 CABALVER=1.18 OPTS="--constraint=hashable<1.2" - GHCVER=7.8.3 CABALVER=1.18 OPTS=-f-hashable+ - GHCVER=7.8.3 CABALVER=1.18 OPTS=-f-template-haskell+ - GHCVER=7.8.3 CABALVER=1.18 OPTS=-f-binary # NOTE: we can't use Cabal 1.20 yet due to # https://github.com/haskell/cabal/issues/1806 - GHCVER=head CABALVER=head
CHANGELOG.markdown view
@@ -1,3 +1,7 @@+1.1+---+* Backported `Lift` instances.+ 1.0 --- * Make `nats` a compat-package since `Numeric.Natural` moved to `base-4.8.0.0`.
nats.cabal view
@@ -1,6 +1,6 @@ name: nats category: Numeric, Algebra-version: 1+version: 1.1 license: BSD3 cabal-version: >= 1.10 license-file: LICENSE@@ -31,21 +31,50 @@ . Disabling this is an unsupported configuration, but it may be useful for accelerating builds in sandboxes for expert users. .- If disabled we will not supply an instance of `Hashable`+ If disabled we will not supply an instance of `Hashable`. default: True manual: True +flag binary+ description:+ You can disable the use of the `binary` package using `-f-binary`.+ .+ Disabling this is an unsupported configuration, but it may be useful for accelerating builds in sandboxes for expert users.+ .+ If disabled we will not supply an instance of `Binary`.+ default: True+ manual: True++flag template-haskell+ description:+ You can disable the use of the `template-haskell` package using `-f-template-haskell`.+ .+ Disabling this is an unsupported configuration, but it may be useful for accelerating builds in sandboxes for expert users.+ .+ If disabled we will not supply an instance of `Lift`.+ default: True+ manual: True+ library default-language: Haskell98 if impl(ghc<7) -- {-# LANGUAGE DeriveDataTypeable #-} is only understood starting w/ GHC-7.0 default-extensions: DeriveDataTypeable - if !impl(ghc>=7.9)+ if impl(ghc<7.9) -- Starting with GHC 7.10/base-4.8, "Numeric.Natural" lives in `base` hs-source-dirs: src exposed-modules: Numeric.Natural ghc-options: -Wall- build-depends: base >= 2 && < 4.8++ -- the needlessly relaxed bound here is to due to stack shenanigans+ build-depends: base >= 2 && < 5++ if flag(binary)+ build-depends: binary >= 0.2 && < 0.8++ if flag(template-haskell)+ build-depends: template-haskell >= 2.2 && < 2.12+ if flag(hashable) build-depends: hashable >= 1.1 && < 1.3
src/Numeric/Natural.hs view
@@ -9,8 +9,8 @@ #define MIN_VERSION_base(x,y,z) 1 #endif -#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 702-#ifdef MIN_VERSION_hashable+#if __GLASGOW_HASKELL__ >= 702+#if defined(MIN_VERSION_hashable) || defined(MIN_VERSION_template_haskell) {-# LANGUAGE Trustworthy #-} #else {-# LANGUAGE Safe #-}@@ -35,15 +35,32 @@ module Numeric.Natural ( Natural ) where import Control.Exception ( throw, ArithException(Underflow) )++#ifdef MIN_VERSION_binary+import Control.Monad (liftM)+import Data.Binary (Binary(..), Get, Word8, Word64, putWord8)+import Data.List (unfoldr)+#endif+ import Data.Bits import Data.Ix+ #ifdef LANGUAGE_DeriveDataTypeable import Data.Data #endif+ #ifdef MIN_VERSION_hashable import Data.Hashable #endif +#ifdef MIN_VERSION_template_haskell+import Language.Haskell.TH.Syntax (Lift(..), Exp(LitE), Lit(IntegerL))+#endif++#if MIN_VERSION_base(4,7,0) && !(MIN_VERSION_base(4,8,0))+import Text.Printf (PrintfArg(..), formatInteger)+#endif+ -- | Type representing arbitrary-precision non-negative integers. -- -- Operations whose result would be negative@@ -78,7 +95,7 @@ instance Data Natural where toConstr x = mkIntegralConstr naturalType x gunfold _ z c = case constrRep c of- (IntConstr x) -> z (fromIntegral x)+ IntConstr x -> z (fromIntegral x) _ -> error $ "Data.Data.gunfold: Constructor " ++ show c ++ " is not of type Natural" dataTypeOf _ = naturalType@@ -131,7 +148,7 @@ {-# INLINE complementBit #-} testBit = testBit . runNatural {-# INLINE testBit #-}-#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 707+#if __GLASGOW_HASKELL__ >= 707 bitSizeMaybe _ = Nothing {-# INLINE bitSizeMaybe #-} #endif@@ -206,3 +223,53 @@ {-# INLINE quotRem #-} toInteger = runNatural {-# INLINE toInteger #-}++#if MIN_VERSION_base(4,7,0) && !(MIN_VERSION_base(4,8,0))+instance PrintfArg Natural where+ formatArg = formatInteger . toInteger+ parseFormat _ = parseFormat (undefined :: Integer)+#endif++#ifdef MIN_VERSION_binary+--+-- Fold and unfold an Integer to and from a list of its bytes+--+unroll :: (Integral a, Num a, Bits a) => a -> [Word8]+unroll = unfoldr step+ where+ step 0 = Nothing+ step i = Just (fromIntegral i, i `shiftR` 8)++roll :: (Integral a, Num a, Bits a) => [Word8] -> a+roll = foldr unstep 0+ where+ unstep b a = a `shiftL` 8 .|. fromIntegral b++-- Fixed-size type for a subset of Natural+type NaturalWord = Word64++instance Binary Natural where+ {-# INLINE put #-}+ put n | n <= hi = do+ putWord8 0+ put (fromIntegral n :: NaturalWord) -- fast path+ where+ hi = fromIntegral (maxBound :: NaturalWord) :: Natural++ put n = do+ putWord8 1+ put (unroll (abs n)) -- unroll the bytes++ {-# INLINE get #-}+ get = do+ tag <- get :: Get Word8+ case tag of+ 0 -> liftM fromIntegral (get :: Get NaturalWord)+ _ -> do bytes <- get+ return $! roll bytes+#endif++#ifdef MIN_VERSION_template_haskell+instance Lift Natural where+ lift x = return (LitE (IntegerL (fromIntegral x)))+#endif