Safe Haskell | Safe-Inferred |
---|---|
Language | Haskell2010 |
An implementation of short vectors.
The underlying implementation uses the SmallArray#
primitive,
which is best-suited for short vectors (less than a few hundred elements).
In contrast to Data.Vec.Short.Explicit, this module provides an API where
bounds parameters are passed implicitly by KnownNat
. This can be more
convenient in cases where the bounds are obvious and type-level arithmetic
is not involved, but it comes at the cost of some runtime
Natural
-to-Int
conversions.
When type-level arithmetic is involved, the
ghc-typelits-knownnat
plugin may be useful to derive KnownNat
instances for bounds automatically.
Synopsis
- data Vec (n :: Nat) (a :: Type)
- mkVec :: KnownNat n => (Fin n -> a) -> Vec n a
- mkVec' :: KnownNat n => (Fin n -> a) -> Vec n a
- backpermute :: KnownNat m => (Fin m -> Fin n) -> Vec n a -> Vec m a
- fromList :: (HasCallStack, KnownNat n) => [a] -> Vec n a
- withVec :: [a] -> (forall n. Vec n a -> r) -> r
- vec1 :: a -> Vec 1 a
- vec2 :: a -> a -> Vec 2 a
- vec3 :: a -> a -> a -> Vec 3 a
- vec4 :: a -> a -> a -> a -> Vec 4 a
- vec6 :: a -> a -> a -> a -> a -> a -> Vec 6 a
- vec8 :: a -> a -> a -> a -> a -> a -> a -> a -> Vec 8 a
- viota :: KnownNat n => Vec n (Fin n)
- svSize :: Vec n a -> SInt n
- vLength :: forall n a. KnownNat n => Vec n a -> Int
- vSize :: Vec n a -> Int
- withSize :: forall n a r. Vec n a -> (KnownNat n => r) -> r
- (!) :: Vec n a -> Fin n -> a
- indexK :: Vec n a -> Fin n -> (a -> r) -> r
- insert :: Fin (n + 1) -> a -> Vec n a -> Vec (n + 1) a
- remove :: Fin (n + 1) -> Vec (n + 1) a -> Vec n a
- overIx :: Fin n -> (a -> a) -> Vec n a -> Vec n a
- nil :: Vec 0 a
- (++) :: Vec n a -> Vec m a -> Vec (n + m) a
- split :: KnownNat m => Vec (m + n) a -> (Vec m a, Vec n a)
- concat :: forall m n a. Vec n (Vec m a) -> Vec (n * m) a
- concatMap :: forall m n a b. (a -> Vec m b) -> Vec n a -> Vec (n * m) b
- reshape :: KnownNat m => Vec (n * m) a -> Vec n (Vec m a)
- rev :: Vec n a -> Vec n a
- rot :: Fin n -> Vec n a -> Vec n a
- vtranspose :: KnownNat m => Vec n (Vec m a) -> Vec m (Vec n a)
- iterate :: KnownNat n => (a -> a) -> a -> Vec n a
- iterate' :: KnownNat n => (a -> a) -> a -> Vec n a
- vsort :: Ord a => Vec n a -> Vec n a
- vsortBy :: (a -> a -> Ordering) -> Vec n a -> Vec n a
- vsortOn :: Ord b => (a -> b) -> Vec n a -> Vec n a
- vfindIndex :: (a -> Bool) -> Vec n a -> Maybe (Fin n)
- map' :: (a -> b) -> Vec n a -> Vec n b
- imap' :: (Fin n -> a -> b) -> Vec n a -> Vec n b
- withPos :: Vec n a -> Vec n (Fin n, a)
- cross :: Vec m a -> Vec n b -> Vec n (Vec m (a, b))
- vscanl :: (b -> a -> b) -> b -> Vec n a -> Vec (1 + n) b
- liftA2Lazy :: KnownNat n => (a -> b -> c) -> Vec n a -> Vec n b -> Vec n c
Documentation
data Vec (n :: Nat) (a :: Type) Source #
is an element-lazy array of Vec
n an
values of type a
.
This comes with a fusion framework, so many intermediate vectors are
optimized away, and generally the only Vecs that correspond to actual arrays
are those stored in data constructors, accessed multiple times, or appearing
as inputs or outputs of non-inlinable functions. Additionally, some
operations that rely on building up a vector incrementally (as opposed to
computing each index independently of the others) cannot be fused; notably
fromList
, traverse
, iterate
, and vscanl
; these will always construct
real arrays for their results.
Most operations are access-strict unless otherwise noted, which means that
forcing the result (usually a Vec, but possibly something else, like with
foldMap
) eagerly performs all indexing and drops references to any input
arrays.
Instances
KnownNat n => Representable (Vec n) Source # | |
Foldable (Vec n) Source # | |
Defined in Data.Vec.Short.Internal fold :: Monoid m => Vec n m -> m # foldMap :: Monoid m => (a -> m) -> Vec n a -> m # foldMap' :: Monoid m => (a -> m) -> Vec n a -> m # foldr :: (a -> b -> b) -> b -> Vec n a -> b # foldr' :: (a -> b -> b) -> b -> Vec n a -> b # foldl :: (b -> a -> b) -> b -> Vec n a -> b # foldl' :: (b -> a -> b) -> b -> Vec n a -> b # foldr1 :: (a -> a -> a) -> Vec n a -> a # foldl1 :: (a -> a -> a) -> Vec n a -> a # elem :: Eq a => a -> Vec n a -> Bool # maximum :: Ord a => Vec n a -> a # minimum :: Ord a => Vec n a -> a # | |
Traversable (Vec n) Source # | |
KnownNat n => Applicative (Vec n) Source # | |
Functor (Vec n) Source # | |
KnownNat n => Monad (Vec n) Source # | |
KnownNat n => Distributive (Vec n) Source # | |
Apply (Vec n) Source # | |
Bind (Vec n) Source # | |
KnownNat n => FoldableWithIndex (Fin n) (Vec n) Source # | |
Defined in Data.Vec.Short.Internal | |
FunctorWithIndex (Fin n) (Vec n) Source # | |
KnownNat n => TraversableWithIndex (Fin n) (Vec n) Source # | |
Defined in Data.Vec.Short.Internal | |
(Arbitrary a, KnownNat n) => Arbitrary (Vec n a) Source # | |
Show a => CoArbitrary (Vec n a) Source # | |
Defined in Data.Vec.Short.Internal coarbitrary :: Vec n a -> Gen b -> Gen b # | |
(KnownNat n, Data a) => Data (Vec n a) Source # | |
Defined in Data.Vec.Short.Internal gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b) -> (forall g. g -> c g) -> Vec n a -> c (Vec n a) # gunfold :: (forall b r. Data b => c (b -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c (Vec n a) # toConstr :: Vec n a -> Constr # dataTypeOf :: Vec n a -> DataType # dataCast1 :: Typeable t => (forall d. Data d => c (t d)) -> Maybe (c (Vec n a)) # dataCast2 :: Typeable t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c (Vec n a)) # gmapT :: (forall b. Data b => b -> b) -> Vec n a -> Vec n a # gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Vec n a -> r # gmapQr :: forall r r'. (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Vec n a -> r # gmapQ :: (forall d. Data d => d -> u) -> Vec n a -> [u] # gmapQi :: Int -> (forall d. Data d => d -> u) -> Vec n a -> u # gmapM :: Monad m => (forall d. Data d => d -> m d) -> Vec n a -> m (Vec n a) # gmapMp :: MonadPlus m => (forall d. Data d => d -> m d) -> Vec n a -> m (Vec n a) # gmapMo :: MonadPlus m => (forall d. Data d => d -> m d) -> Vec n a -> m (Vec n a) # | |
(KnownNat n, Monoid a) => Monoid (Vec n a) Source # | Point-wise |
Semigroup a => Semigroup (Vec n a) Source # | Point-wise |
KnownNat n => IsList (Vec n a) Source # | |
(KnownNat n, Num a) => Num (Vec n a) Source # | |
(KnownNat n, Read a) => Read (Vec n a) Source # | |
Show a => Show (Vec n a) Source # | |
(KnownNat n, Default a) => Default (Vec n a) Source # | |
Defined in Data.Vec.Short.Internal | |
NFData a => NFData (Vec n a) Source # | |
Defined in Data.Vec.Short.Internal | |
Eq a => Eq (Vec n a) Source # | |
Ord a => Ord (Vec n a) Source # | |
Portray a => Portray (Vec n a) Source # | |
Defined in Data.Vec.Short.Internal | |
(Portray a, Diff a) => Diff (Vec n a) Source # | |
type Rep (Vec n) Source # | |
Defined in Data.Vec.Short.Internal | |
type Item (Vec n a) Source # | |
Defined in Data.Vec.Short.Internal |
Core constructors/generators
Fin
-based constructors
mkVec' :: KnownNat n => (Fin n -> a) -> Vec n a Source #
Create a known-length vector using a pure function, strictly.
List-based constructors
fromList :: (HasCallStack, KnownNat n) => [a] -> Vec n a Source #
Convert a list to a vector, throwing an error if the list has the
wrong length.
Note: Because this walks xs
to check its length, this cannot be
used with the list fusion optimization rules.
withVec :: [a] -> (forall n. Vec n a -> r) -> r Source #
Convert a list to a vector of the same length.
Arity-based constructors
Enum
-based constructors
viota :: KnownNat n => Vec n (Fin n) Source #
Return a vector with all elements of the type in ascending order.
Core operators
Size/length
Indexing
(!) :: Vec n a -> Fin n -> a Source #
Extract the given index from a Vec
.
This is subject to fusion if this is the only use of its input, so code like
fmap f v ! i
(which might arise due to inlining) will optimize to
f (v ! i)
.
indexK :: Vec n a -> Fin n -> (a -> r) -> r Source #
Eagerly look up the value at a given position, without forcing the value itself.
One of the problems with (!)
is that it will hold onto the underlying
array until the xs!i
expression is forced; which is a source of
space leaks. However, forcing the xs!i
expression will force
not only the array lookup but also the value itself; which can be
undesirably strict, thereby ruining the compositionality benefits
of laziness. The indexK
function is designed to overcome those
limitations. That is, forcing the expression indexK xs i k
will
force the array lookup and the r
value; thereby leaving it up to
k
to decide whether or not to force the a
before returning r
.
So, for example, if we force indexK xs i Just
this will force the
array lookup, and wrap the unforced element in the Just
constructor.
Add/remove element
insert :: Fin (n + 1) -> a -> Vec n a -> Vec (n + 1) a Source #
Insert an element at the given position in a vector. O(n)
remove :: Fin (n + 1) -> Vec (n + 1) a -> Vec n a Source #
Remove an element at the given position in a vector. O(n)
List-like operators
Constructor views
The nil view
Operator views
The append view
split :: KnownNat m => Vec (m + n) a -> (Vec m a, Vec n a) Source #
Split a Vec
into two at a given offset.
The concat view
The reverse view
rot :: Fin n -> Vec n a -> Vec n a Source #
Rotate a vector right by i
positions.
rot 1 [x, y, z] = [z, x, y]
The transposition view
vtranspose :: KnownNat m => Vec n (Vec m a) -> Vec m (Vec n a) Source #
Transpose a vector of vectors.
Misc list-like operators
iterate :: KnownNat n => (a -> a) -> a -> Vec n a Source #
Generate a Vec by repeated application of a function.
toList (Vec.iterate @n f z) === take (valueOf @n) (Prelude.iterate f z)
vsortBy :: (a -> a -> Ordering) -> Vec n a -> Vec n a Source #
Sort a Vec
with a given comparison function.
vsortOn :: Ord b => (a -> b) -> Vec n a -> Vec n a Source #
Sort a Vec
with a given sort-key function.
vfindIndex :: (a -> Bool) -> Vec n a -> Maybe (Fin n) Source #
Find the index of the first element, if any, that satisfies a predicate.