nonempty-vector 0.2.0.2 → 0.2.1.0
raw patch · 5 files changed
+197/−115 lines, 5 filesdep ~basedep ~vector
Dependency ranges changed: base, vector
Files
- CHANGELOG.md +12/−0
- nonempty-vector.cabal +26/−21
- src/Data/Vector/NonEmpty.hs +28/−74
- src/Data/Vector/NonEmpty/Internal.hs +128/−0
- src/Data/Vector/NonEmpty/Mutable.hs +3/−20
CHANGELOG.md view
@@ -1,5 +1,17 @@ # Revision history for nonempty-vector +## 0.2.1.0++* Added `consV` and `snocV` primitives for consing a vector to create a nonempty one. [(#8)](https://github.com/emilypi/nonempty-vector/pull/8) - Thanks @AlistairB!+* Updated CI and cabal support+* Expose constructors in new `Data.Vector.NonEmpty.Internal` module+* Modules are now marked trustworthy+* `@since` annotations have been added.++## 0.2.0.2++* Removed spurious dependency on `semigroups`+ ## 0.2.0.1 * Missed a strictness tick in `postscanl'`
nonempty-vector.cabal view
@@ -1,25 +1,29 @@-cabal-version: 2.0-name: nonempty-vector-version: 0.2.0.2-synopsis: Non-empty vectors-description:- Performant non-empty mutable and immutable vectors.--homepage: https://github.com/emilypi/nonempty-vector-bug-reports: https://github.com/emilypi/nonempty-vector/issues-license: BSD3-license-file: LICENSE-author: Emily Pillmore-maintainer: emilypi@cohomolo.gy-copyright: (c) 2019 Emily Pillmore-category: Data-build-type: Custom-extra-source-files:+cabal-version: 1.24+name: nonempty-vector+version: 0.2.1.0+synopsis: Non-empty vectors+description: Performant, non-empty mutable and immutable vectors+homepage: https://github.com/emilypi/nonempty-vector+bug-reports: https://github.com/emilypi/nonempty-vector/issues+license: BSD3+license-file: LICENSE+author: Emily Pillmore+maintainer: emilypi@cohomolo.gy+copyright: (c) 2019-2020 Emily Pillmore <emilypi@cohomolo.gy>+category: Data+build-type: Custom+extra-doc-files: CHANGELOG.md README.md tested-with:- GHC ==8.2.2 || ==8.4.4 || ==8.6.5 || ==8.8.3 || ==8.10.1+ GHC ==8.0.2+ || ==8.4.3+ || ==8.4.4+ || ==8.6.3+ || ==8.6.5+ || ==8.8.1+ || ==8.10.2 source-repository head type: git@@ -34,13 +38,14 @@ library exposed-modules: Data.Vector.NonEmpty+ Data.Vector.NonEmpty.Internal Data.Vector.NonEmpty.Mutable build-depends:- base >=4.10 && <5+ base >=4.9 && <5 , deepseq , primitive >=0.6 && <0.8- , vector ^>=0.12+ , vector >=0.12 && <0.13 hs-source-dirs: src default-language: Haskell2010@@ -51,7 +56,7 @@ type: exitcode-stdio-1.0 main-is: doctests.hs build-depends:- base >=4.10 && <5+ base >=4.9 && <5 , doctest hs-source-dirs: test
src/Data/Vector/NonEmpty.hs view
@@ -1,11 +1,9 @@-{-# LANGUAGE CPP #-}-{-# LANGUAGE DeriveDataTypeable #-}-{-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE NoImplicitPrelude #-} {-# LANGUAGE Rank2Types #-}+{-# LANGUAGE Trustworthy #-} -- | -- Module : Data.Vector.NonEmpty--- Copyright : (c) 2019 Emily Pillmore+-- Copyright : (c) 2019-2020 Emily Pillmore -- License : BSD-style -- -- Maintainer : Emily Pillmore <emilypi@cohomolo.gy>@@ -90,7 +88,7 @@ , enumFromTo, enumFromThenTo -- ** Concatenation-, cons, snoc, (++), concat, concat1+, cons, consV, snoc, snocV, (++), concat, concat1 -- ** Restricting memory usage , force@@ -186,40 +184,29 @@ ) where -import Prelude ( Bool, Eq, Ord, Show(..), Num, Enum+import Prelude ( Bool, Eq, Ord, Num, Enum , (.), Ordering, max, uncurry, snd) --import Control.Applicative-import Control.DeepSeq hiding (force)-import Control.Monad (Monad, return)+import Control.Monad (Monad) import Control.Monad.ST-import Control.Monad.Zip (MonadZip) -import Data.Data (Data)-import Data.Foldable (Foldable) import qualified Data.Foldable as Foldable import Data.Functor-import Data.Functor.Classes (Eq1, Ord1, Show1, Read1(..)) import Data.Int import Data.List.NonEmpty (NonEmpty(..)) import qualified Data.List.NonEmpty as NonEmpty import Data.Maybe (Maybe(..)) import Data.Semigroup (Semigroup(..), (<>))-import Data.Traversable (Traversable, traverse)-import Data.Typeable (Typeable)+import Data.Traversable (Traversable) import Data.Vector (Vector) import qualified Data.Vector as V import qualified Data.Vector.Generic as G import Data.Vector.Mutable (MVector)--import GHC.Read--import qualified Text.Read as Read+import Data.Vector.NonEmpty.Internal -- $setup--- >>> import Prelude (Int, String, ($), (.), (+), (<), const)+-- >>> import Prelude (Int, String, ($), (.), (+), (<), const, return) -- >>> import Data.Bool -- >>> import Data.Eq -- >>> import qualified Prelude as P@@ -229,57 +216,6 @@ -- >>> :set -XTypeApplications -- >>> :set -XScopedTypeVariables ---- | 'NonEmptyVector' is a thin wrapper around 'Vector' that--- witnesses an API requiring non-empty construction,--- initialization, and generation of non-empty vectors by design.------ A newtype wrapper was chosen so that no new pointer indirection--- is introduced when working with 'Vector's, and all performance--- characteristics inherited from the 'Vector' API still apply.----newtype NonEmptyVector a = NonEmptyVector- { _neVec :: V.Vector a- } deriving- ( Eq, Ord- , Eq1, Ord1, Show1- , Data, Typeable, NFData- , Functor, Applicative, Monad- , MonadZip- , Semigroup- )--instance Show a => Show (NonEmptyVector a) where- show (NonEmptyVector v) = show v--instance Read a => Read (NonEmptyVector a) where- readPrec = do- as <- Read.readPrec- if Foldable.null as- then Read.pfail- else return (unsafeFromList as)--instance Read1 NonEmptyVector where-#if __GLASGOW_HASKELL__ > 802- liftReadPrec _ rl = do- l <- rl- if Foldable.null l- then Read.pfail- else return (unsafeFromList l)-#else- liftReadsPrec _ r _ s = do- (as, s') <- r s- if Foldable.null as- then []- else return (unsafeFromList as, s')-#endif--instance Foldable NonEmptyVector where- foldMap f = Foldable.foldMap f . _neVec--instance Traversable NonEmptyVector where- traverse f = fmap NonEmptyVector . traverse f . _neVec- -- ---------------------------------------------------------------------- -- -- Accessors + Indexing @@ -1049,17 +985,35 @@ -- [1,2,3] -- cons :: a -> NonEmptyVector a -> NonEmptyVector a-cons a (NonEmptyVector as) = NonEmptyVector (V.cons a as)+cons a (NonEmptyVector as) = consV a as {-# INLINE cons #-} +-- | /O(n)/ Prepend an element to a Vector+--+-- >>> consV 1 (V.fromList [2,3])+-- [1,2,3]+--+consV :: a -> Vector a -> NonEmptyVector a+consV a = NonEmptyVector . V.cons a+{-# INLINE consV #-}+ -- | /O(n)/ Append an element -- -- >>> snoc (unsafeFromList [1,2]) 3 -- [1,2,3] -- snoc :: NonEmptyVector a -> a -> NonEmptyVector a-snoc (NonEmptyVector as) a = NonEmptyVector (V.snoc as a)+snoc (NonEmptyVector as) = snocV as {-# INLINE snoc #-}++-- | /O(n)/ Append an element to a Vector+--+-- >>> snocV (V.fromList [1,2]) 3+-- [1,2,3]+--+snocV :: Vector a -> a -> NonEmptyVector a+snocV as = NonEmptyVector . V.snoc as+{-# INLINE snocV #-} -- | /O(m+n)/ Concatenate two non-empty vectors --
+ src/Data/Vector/NonEmpty/Internal.hs view
@@ -0,0 +1,128 @@+{-# LANGUAGE CPP #-}+{-# LANGUAGE DeriveDataTypeable #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE LambdaCase #-}+{-# LANGUAGE Trustworthy #-}+-- |+-- Module : Data.Vector.NonEmpty.Internal+-- Copyright : (c) 2019-2020 Emily Pillmore+-- License : BSD-style+--+-- Maintainer : Emily Pillmore <emilypi@cohomolo.gy>+-- Stability : experimental+-- Portability : non-portable+--+-- Internal module exposing the constructors for+-- 'NonEmptyVector' and 'NonEmptyMVector'.+--+-- /Warning/: Since the constructors are exposed here, by using this+-- module, you take on the risks that you break the non-emptiness+-- invariants of the main modules. Use at your own risk.+--+-- @since 0.2.1.0+--+module Data.Vector.NonEmpty.Internal+( -- * Immutable boxed vectors+ NonEmptyVector(..)+ -- * Mutable boxed vectors+, NonEmptyMVector(..)+ -- ** Mutable vector aliases+, NonEmptyIOVector+, NonEmptySTVector+) where+++import Control.DeepSeq (NFData)+import Control.Monad.ST+import Control.Monad.Zip (MonadZip)++import Data.Data (Data)+import qualified Data.Foldable as Foldable+import Data.Functor.Classes (Eq1, Ord1, Show1, Read1(..))+import qualified Data.Vector as V+#if __GLASGOW_HASKELL__ < 804+import Data.Semigroup (Semigroup(..))+#endif+import Data.Typeable (Typeable)+import Data.Vector.Mutable (MVector)++import qualified Text.Read as Read+++-- ---------------------------------------------------------------------- --+-- Non-empty immutable vectors++-- | 'NonEmptyVector' is a thin wrapper around 'Vector' that+-- witnesses an API requiring non-empty construction,+-- initialization, and generation of non-empty vectors by design.+--+-- A newtype wrapper was chosen so that no new pointer indirection+-- is introduced when working with 'Vector's, and all performance+-- characteristics inherited from the 'Vector' API still apply.+--+-- @since 0.2.1.0+--+newtype NonEmptyVector a = NonEmptyVector+ { _neVec :: V.Vector a+ } deriving+ ( Eq, Ord+ , Eq1, Ord1, Show1+ , Data, Typeable, NFData+ , Functor, Applicative, Monad+ , MonadZip+ , Semigroup+ )++instance Show a => Show (NonEmptyVector a) where+ show (NonEmptyVector v) = show v++instance Read a => Read (NonEmptyVector a) where+ readPrec = Read.readPrec >>= \case+ [] -> Read.pfail+ as -> return (NonEmptyVector $ V.fromList as)++instance Read1 NonEmptyVector where+#if __GLASGOW_HASKELL__ > 802+ liftReadPrec _ rl = rl >>= \case+ [] -> Read.pfail+ as -> return (NonEmptyVector $ V.fromList as)+#else+ liftReadsPrec _ r _ s = r s >>= \case+ ([], _) -> []+ (as, s') -> return (NonEmptyVector $ V.fromList as, s')+#endif++instance Foldable NonEmptyVector where+ foldMap f = Foldable.foldMap f . _neVec++instance Traversable NonEmptyVector where+ traverse f = fmap NonEmptyVector . traverse f . _neVec++-- ---------------------------------------------------------------------- --+-- Non-empty mutable vectors++-- | 'NonEmptyMVector' is a thin wrapper around 'MVector' that+-- witnesses an API requiring non-empty construction,+-- initialization, and generation of non-empty vectors by design.+--+-- A newtype wrapper was chosen so that no new pointer indirection+-- is introduced when working with 'MVector's, and all performance+-- characteristics inherited from the 'MVector' API still apply.+--+-- @since 0.2.1.0+--+newtype NonEmptyMVector s a = NonEmptyMVector+ { _nemVec :: MVector s a }+ deriving (Typeable)++-- | 'NonEmptyMVector' parametrized by 'PrimState'+--+-- @since 0.2.1.0+--+type NonEmptyIOVector = NonEmptyMVector RealWorld++-- | 'NonEmptyMVector' parametrized by 'ST'+--+-- @since 0.2.1.0+--+type NonEmptySTVector s = NonEmptyMVector s
src/Data/Vector/NonEmpty/Mutable.hs view
@@ -1,9 +1,10 @@ {-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE BangPatterns #-} {-# LANGUAGE NoImplicitPrelude #-}+{-# LANGUAGE Trustworthy #-} -- | -- Module : Data.Vector.NonEmpty.Mutable--- Copyright : (c) 2019 Emily Pillmore+-- Copyright : (c) 2019-2020 Emily Pillmore -- License : BSD-style -- -- Maintainer : Emily Pillmore <emilypi@cohomolo.gy>@@ -62,28 +63,10 @@ import Data.Functor import Data.Maybe (Maybe(..))-import Data.Typeable (Typeable) import Data.Vector.Mutable (MVector) import qualified Data.Vector.Mutable as M----- | 'NonEmptyMVector' is a thin wrapper around 'MVector' that--- witnesses an API requiring non-empty construction,--- initialization, and generation of non-empty vectors by design.------ A newtype wrapper was chosen so that no new pointer indirection--- is introduced when working with 'MVector's, and all performance--- characteristics inherited from the 'MVector' API still apply.----newtype NonEmptyMVector s a = NonEmptyMVector- { _nemVec :: MVector s a }- deriving (Typeable)---- | 'NonEmptyMVector' parametrized by 'PrimState'-type NonEmptyIOVector = NonEmptyMVector RealWorld+import Data.Vector.NonEmpty.Internal --- | 'NonEmptyMVector' parametrized by 'ST'-type NonEmptySTVector s = NonEmptyMVector s -- ---------------------------------------------------------------------- -- -- Length information