vector-sized (empty) → 0.1.0.0
raw patch · 7 files changed
+388/−0 lines, 7 filesdep +basedep +deepseqdep +vectorsetup-changed
Dependencies added: base, deepseq, vector
Files
- LICENSE +30/−0
- Setup.hs +2/−0
- changelog.md +4/−0
- readme.md +13/−0
- src/Data/Vector/Generic/Sized.hs +175/−0
- src/Data/Vector/Storable/Sized.hs +136/−0
- vector-sized.cabal +28/−0
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright Joe Hermaszewski (c) 2016++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 Joe Hermaszewski 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
+ changelog.md view
@@ -0,0 +1,4 @@+# Change Log++## [0.1.0.0] - 2016-02-28+Initial release.
+ readme.md view
@@ -0,0 +1,13 @@+# Vector Sized++This package exports a newtype tagging the vectors from the+[vector](https://hackage.haskell.org/package/vector) package with a type level+natural representing their size.++It also exports a few functions from vector appropriately retyped.++This package is fairly similar to the+[fixed-vector](https://hackage.haskell.org/package/fixed-vector) package. The+difference is that fixed-vector uses Peano naturals to represent the size tag+on the vectors and this package uses typelits.+
+ src/Data/Vector/Generic/Sized.hs view
@@ -0,0 +1,175 @@+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE KindSignatures #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeOperators #-}++module Data.Vector.Generic.Sized+ ( Vector+ -- * Construction+ , fromVector+ , replicate+ , singleton+ , generate+ -- * Monadic Construction+ , generateM+ -- * Elimination+ , length+ , index+ , head+ , last+ -- * Extract subsets+ , tail+ , init+ , take+ , drop+ -- * Mapping+ , map+ -- * Monadic Mapping+ , imapM_+ -- * Folding+ , foldl'+ , foldl1'+ ) where++import qualified Data.Vector.Generic as VG+import qualified Data.Vector.Storable as VS+import GHC.TypeLits+import Data.Proxy+import Control.DeepSeq+import Foreign.Storable+import Foreign.Ptr (castPtr)+import Prelude hiding (replicate, head, last,+ tail, init, map, length, drop, take)++newtype Vector v (n :: Nat) a = Vector (v a)+ deriving (Show, Eq, Ord, Foldable, NFData)++instance (KnownNat n, Storable a) + => Storable (Vector VS.Vector n a) where+ sizeOf _ = sizeOf (undefined :: a) * fromIntegral (natVal (Proxy :: Proxy n))+ alignment _ = alignment (undefined :: a)+ peek ptr = generateM (Proxy :: Proxy n) (peekElemOff (castPtr ptr))+ poke ptr = imapM_ (pokeElemOff (castPtr ptr))++-- | Convert a 'Data.Vector.Generic.Vector' into a+-- 'Data.Vector.Generic.Sized.Vector' if it has the correct size, otherwise+-- return Nothing.+fromVector :: forall a v (n :: Nat). (KnownNat n, VG.Vector v a)+ => v a -> Maybe (Vector v n a)+fromVector v+ | n' == fromIntegral (VG.length v) = Just (Vector v)+ | otherwise = Nothing+ where n' = natVal (Proxy :: Proxy n)+{-# INLINE fromVector #-}++-- | /O(1)/ construct a single element vector.+singleton :: forall a v. (VG.Vector v a)+ => a -> Vector v 1 a+singleton a = Vector (VG.singleton a)+{-# INLINE singleton #-}++-- | /O(n)/ construct a vector of the given length by applying the function to+-- each index.+generate :: forall (n :: Nat) a v. (VG.Vector v a, KnownNat n)+ => Proxy n -> (Int -> a) -> Vector v n a+generate n f = Vector (VG.generate (fromIntegral $ natVal n) f)+{-# INLINE generate #-}++-- | /O(n)/ construct a vector of the given length by applying the monadic+-- action to each index.+generateM :: forall (n :: Nat) a v m. (VG.Vector v a, KnownNat n, Monad m)+ => Proxy n -> (Int -> m a) -> m (Vector v n a)+generateM n f = Vector <$> VG.generateM (fromIntegral $ natVal n) f+{-# INLINE generateM #-}++-- | Apply a function on unsized vectors to a sized vector. The function must+-- preserve the size of the vector, this is not checked.+withVectorUnsafe :: forall a b v (n :: Nat). (VG.Vector v a, VG.Vector v b)+ => (v a -> v b) -> Vector v n a -> Vector v n b+withVectorUnsafe f (Vector v) = Vector (f v)+{-# INLINE withVectorUnsafe #-}++-- | /O(1)/ Index safely into the vector using a type level index.+index :: forall (m :: Nat) a v (n :: Nat). (KnownNat n, KnownNat m, VG.Vector v a)+ => Vector v (m+n) a -> Proxy n -> a+index (Vector v) i = v `VG.unsafeIndex` fromIntegral (natVal i)+{-# INLINE index #-}++-- | /O(1)/ Yield the first n elements. The resultant vector always contains+-- this many elements.+take :: forall (m :: Nat) a v (n :: Nat). (KnownNat n, KnownNat m, VG.Vector v a)+ => Proxy n -> Vector v (m+n) a -> Vector v n a+take i (Vector v) = Vector (VG.take (fromIntegral $ natVal i) v)+{-# INLINE take #-}++-- | /O(1)/ Yield all but the first n elements.+drop :: forall (m :: Nat) a v (n :: Nat). (KnownNat n, KnownNat m, VG.Vector v a)+ => Proxy n -> Vector v (m+n) a -> Vector v m a+drop i (Vector v) = Vector (VG.drop (fromIntegral $ natVal i) v)+{-# INLINE drop #-}++-- | /O(1)/ Get the length of the vector.+length :: forall a v (n :: Nat). (VG.Vector v a)+ => Vector v n a -> Int+length (Vector v) = VG.length v+{-# INLINE length #-}++-- | /O(1)/ Get the first element of a non-empty vector.+head :: forall a v (n :: Nat). (VG.Vector v a)+ => Vector v (n+1) a -> a+head (Vector v) = VG.head v+{-# INLINE head #-}++-- | /O(1)/ Get the last element of a non-empty vector.+last :: forall a v (n :: Nat). (VG.Vector v a)+ => Vector v (n+1) a -> a+last (Vector v) = VG.last v+{-# INLINE last #-}++-- | /O(1)/ Yield all but the first element of a non-empty vector without+-- copying.+tail :: forall a v (n :: Nat). (VG.Vector v a)+ => Vector v (n+1) a -> Vector v n a+tail (Vector v) = Vector (VG.tail v)+{-# INLINE tail #-}++-- | /O(1)/ Yield all but the last element of a non-empty vector without+-- copying.+init :: forall a v (n :: Nat). (VG.Vector v a)+ => Vector v (n+1) a -> Vector v n a+init (Vector v) = Vector (VG.init v)+{-# INLINE init #-}++-- | /O(n)/ Construct a vector with the same element in each position.+replicate :: forall a v (n :: Nat). (VG.Vector v a, KnownNat n)+ => a -> Vector v n a+replicate a = Vector (VG.replicate (fromIntegral $ natVal (Proxy :: Proxy n)) a)+{-# INLINE replicate #-}++-- | /O(n)/ Map a function over the vector.+map :: forall a b v (n :: Nat). (VG.Vector v a, VG.Vector v b)+ => (a -> b) -> Vector v n a -> Vector v n b+map f = withVectorUnsafe (VG.map f)+{-# INLINE map #-}++-- | /O(n)/ Apply the monadic action to every element of a vector and its+-- index, ignoring the results.+imapM_ :: forall a v n b m. (VG.Vector v a, Monad m)+ => (Int -> a -> m b) -> Vector v n a -> m ()+imapM_ f (Vector v) = VG.imapM_ f v+{-# INLINE imapM_ #-}++-- | /O(n)/ Left fold with a strict accumulator.+foldl' :: forall a b v (n :: Nat). VG.Vector v b+ => (a -> b -> a) -> a -> Vector v n b -> a+foldl' f z (Vector v) = VG.foldl' f z v+{-# INLINE foldl' #-}++-- | /O(n)/ Left fold on a non-empty vector with a strict accumulator.+foldl1' :: forall a v (n :: Nat). (VG.Vector v a)+ => (a -> a -> a) -> Vector v (n+1) a -> a+foldl1' f (Vector v) = VG.foldl1' f v+{-# INLINE foldl1' #-}
+ src/Data/Vector/Storable/Sized.hs view
@@ -0,0 +1,136 @@+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE KindSignatures #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE DataKinds #-}++module Data.Vector.Storable.Sized+ ( Vector+ -- * Construction+ , fromVector+ , replicate+ , singleton+ , generate+ -- * Elimination+ , length+ , index+ , head+ , last+ -- * Extract subsets+ , tail+ , init+ , take+ , drop+ -- * Mapping+ , map+ -- * Folding+ , foldl'+ , foldl1'+ ) where++import qualified Data.Vector.Generic.Sized as VGS+import qualified Data.Vector.Storable as VS+import GHC.TypeLits+import Data.Proxy+import Foreign.Storable+import Prelude hiding (replicate, head, last,+ tail, init, map, length, drop, take)++type Vector = VGS.Vector VS.Vector++-- | Convert a 'Data.Vector.Generic.Vector' into a+-- 'Data.Vector.Generic.Sized.Vector' if it has the correct size, otherwise+-- return Nothing.+fromVector :: forall a (n :: Nat). (KnownNat n, Storable a)+ => VS.Vector a -> Maybe (Vector n a)+fromVector = VGS.fromVector+{-# INLINE fromVector #-}++-- | /O(1)/ construct a single element vector.+singleton :: forall a. Storable a+ => a -> Vector 1 a+singleton = VGS.singleton+{-# INLINE singleton #-}++-- | /O(n)/ construct a vector of the given length by applying the function to+-- each index.+generate :: forall (n :: Nat) a. (Storable a, KnownNat n)+ => Proxy n -> (Int -> a) -> Vector n a+generate = VGS.generate+{-# INLINE generate #-}++-- | /O(1)/ Index safely into the vector using a type level index.+index :: forall (m :: Nat) a (n :: Nat). (KnownNat n, KnownNat m, Storable a)+ => Vector (m+n) a -> Proxy n -> a+index = VGS.index+{-# INLINE index #-}++-- | /O(1)/ Yield the first n elements. The resultant vector always contains+-- this many elements.+take :: forall (m :: Nat) a (n :: Nat). (KnownNat n, KnownNat m, Storable a)+ => Proxy n -> Vector (m+n) a -> Vector n a+take = VGS.take+{-# INLINE take #-}++-- | /O(1)/ Yield all but the first n elements.+drop :: forall (m :: Nat) a (n :: Nat). (KnownNat n, KnownNat m, Storable a)+ => Proxy n -> Vector (m+n) a -> Vector m a+drop = VGS.drop+{-# INLINE drop #-}++-- | /O(1)/ Get the length of the vector.+length :: forall a (n :: Nat). (Storable a)+ => Vector n a -> Int+length = VGS.length+{-# INLINE length #-}++-- | /O(1)/ Get the first element of a non-empty vector.+head :: forall a (n :: Nat). (Storable a)+ => Vector (n+1) a -> a+head = VGS.head+{-# INLINE head #-}++-- | /O(1)/ Get the last element of a non-empty vector.+last :: forall a (n :: Nat). (Storable a)+ => Vector (n+1) a -> a+last = VGS.last+{-# INLINE last #-}++-- | /O(1)/ Yield all but the first element of a non-empty vector without+-- copying.+tail :: forall a (n :: Nat). (Storable a)+ => Vector (n+1) a -> Vector n a+tail = VGS.tail+{-# INLINE tail #-}++-- | /O(1)/ Yield all but the last element of a non-empty vector without+-- copying.+init :: forall a (n :: Nat). (Storable a)+ => Vector (n+1) a -> Vector n a+init = VGS.init+{-# INLINE init #-}++-- | /O(n)/ Construct a vector with the same element in each position.+replicate :: forall a (n :: Nat). (Storable a, KnownNat n)+ => a -> Vector n a+replicate = VGS.replicate+{-# INLINE replicate #-}++-- | /O(n)/ Map a function over the vector.+map :: forall a b (n :: Nat). (Storable a, Storable b)+ => (a -> b) -> Vector n a -> Vector n b+map = VGS.map+{-# INLINE map #-}++-- | /O(n)/ Left fold with a strict accumulator.+foldl' :: forall a b (n :: Nat). Storable b+ => (a -> b -> a) -> a -> Vector n b -> a+foldl' = VGS.foldl'+{-# INLINE foldl' #-}++-- | /O(n)/ Left fold on a non-empty vector with a strict accumulator.+foldl1' :: forall a (n :: Nat). Storable a+ => (a -> a -> a) -> Vector (n+1) a -> a+foldl1' = VGS.foldl1'+{-# INLINE foldl1' #-}
+ vector-sized.cabal view
@@ -0,0 +1,28 @@+name: vector-sized+version: 0.1.0.0+synopsis: Size tagged vectors+description: Please see README.md+homepage: http://github.com/expipiplus1/vector-sized#readme+license: BSD3+license-file: LICENSE+author: Joe Hermaszewski+maintainer: whats.our.vector.victor@monoid.al+copyright: 2016 Joe Hermaszewski+category: Data+build-type: Simple+extra-source-files: readme.md+ , changelog.md+cabal-version: >=1.10++library+ hs-source-dirs: src+ exposed-modules: Data.Vector.Generic.Sized+ , Data.Vector.Storable.Sized+ build-depends: base >= 4.7 && < 5+ , vector >= 0.11 && < 0.12+ , deepseq >= 1.1 && < 1.5+ default-language: Haskell2010++source-repository head+ type: git+ location: https://github.com/expipiplus1/vector-sized