vec-0.3: Vec: length-indexed (sized) list

Safe HaskellNone
LanguageHaskell2010

Data.Vec.Lazy

Contents

Description

Lazy (in elements and spine) length-indexed list: Vec.

Synopsis

Documentation

data Vec (n :: Nat) a where Source #

Vector, i.e. length-indexed list.

Constructors

VNil :: Vec Z a 
(:::) :: a -> Vec n a -> Vec (S n) a infixr 5 
Instances
SNatI n => Monad (Vec n) Source # 
Instance details

Defined in Data.Vec.Lazy

Methods

(>>=) :: Vec n a -> (a -> Vec n b) -> Vec n b #

(>>) :: Vec n a -> Vec n b -> Vec n b #

return :: a -> Vec n a #

fail :: String -> Vec n a #

Functor (Vec n) Source # 
Instance details

Defined in Data.Vec.Lazy

Methods

fmap :: (a -> b) -> Vec n a -> Vec n b #

(<$) :: a -> Vec n b -> Vec n a #

SNatI n => Applicative (Vec n) Source # 
Instance details

Defined in Data.Vec.Lazy

Methods

pure :: a -> Vec n a #

(<*>) :: Vec n (a -> b) -> Vec n a -> Vec n b #

liftA2 :: (a -> b -> c) -> Vec n a -> Vec n b -> Vec n c #

(*>) :: Vec n a -> Vec n b -> Vec n b #

(<*) :: Vec n a -> Vec n b -> Vec n a #

Foldable (Vec n) Source # 
Instance details

Defined in Data.Vec.Lazy

Methods

fold :: Monoid m => Vec n m -> 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 #

toList :: Vec n a -> [a] #

null :: Vec n a -> Bool #

length :: Vec n a -> Int #

elem :: Eq a => a -> Vec n a -> Bool #

maximum :: Ord a => Vec n a -> a #

minimum :: Ord a => Vec n a -> a #

sum :: Num a => Vec n a -> a #

product :: Num a => Vec n a -> a #

Traversable (Vec n) Source # 
Instance details

Defined in Data.Vec.Lazy

Methods

traverse :: Applicative f => (a -> f b) -> Vec n a -> f (Vec n b) #

sequenceA :: Applicative f => Vec n (f a) -> f (Vec n a) #

mapM :: Monad m => (a -> m b) -> Vec n a -> m (Vec n b) #

sequence :: Monad m => Vec n (m a) -> m (Vec n a) #

SNatI n => Arbitrary1 (Vec n) Source # 
Instance details

Defined in Data.Vec.Lazy

Methods

liftArbitrary :: Gen a -> Gen (Vec n a) #

liftShrink :: (a -> [a]) -> Vec n a -> [Vec n a] #

SNatI n => Distributive (Vec n) Source # 
Instance details

Defined in Data.Vec.Lazy

Methods

distribute :: Functor f => f (Vec n a) -> Vec n (f a) #

collect :: Functor f => (a -> Vec n b) -> f a -> Vec n (f b) #

distributeM :: Monad m => m (Vec n a) -> Vec n (m a) #

collectM :: Monad m => (a -> Vec n b) -> m a -> Vec n (m b) #

SNatI n => Representable (Vec n) Source # 
Instance details

Defined in Data.Vec.Lazy

Associated Types

type Rep (Vec n) :: Type #

Methods

tabulate :: (Rep (Vec n) -> a) -> Vec n a #

index :: Vec n a -> Rep (Vec n) -> a #

n ~ S m => Traversable1 (Vec n) Source # 
Instance details

Defined in Data.Vec.Lazy

Methods

traverse1 :: Apply f => (a -> f b) -> Vec n a -> f (Vec n b) #

sequence1 :: Apply f => Vec n (f b) -> f (Vec n b) #

n ~ S m => Foldable1 (Vec n) Source # 
Instance details

Defined in Data.Vec.Lazy

Methods

fold1 :: Semigroup m => Vec n m -> m #

foldMap1 :: Semigroup m => (a -> m) -> Vec n a -> m #

toNonEmpty :: Vec n a -> NonEmpty a #

Apply (Vec n) Source # 
Instance details

Defined in Data.Vec.Lazy

Methods

(<.>) :: Vec n (a -> b) -> Vec n a -> Vec n b #

(.>) :: Vec n a -> Vec n b -> Vec n b #

(<.) :: Vec n a -> Vec n b -> Vec n a #

liftF2 :: (a -> b -> c) -> Vec n a -> Vec n b -> Vec n c #

Bind (Vec n) Source # 
Instance details

Defined in Data.Vec.Lazy

Methods

(>>-) :: Vec n a -> (a -> Vec n b) -> Vec n b #

join :: Vec n (Vec n a) -> Vec n a #

Eq a => Eq (Vec n a) Source # 
Instance details

Defined in Data.Vec.Lazy

Methods

(==) :: Vec n a -> Vec n a -> Bool #

(/=) :: Vec n a -> Vec n a -> Bool #

Ord a => Ord (Vec n a) Source # 
Instance details

Defined in Data.Vec.Lazy

Methods

compare :: Vec n a -> Vec n a -> Ordering #

(<) :: Vec n a -> Vec n a -> Bool #

(<=) :: Vec n a -> Vec n a -> Bool #

(>) :: Vec n a -> Vec n a -> Bool #

(>=) :: Vec n a -> Vec n a -> Bool #

max :: Vec n a -> Vec n a -> Vec n a #

min :: Vec n a -> Vec n a -> Vec n a #

Show a => Show (Vec n a) Source # 
Instance details

Defined in Data.Vec.Lazy

Methods

showsPrec :: Int -> Vec n a -> ShowS #

show :: Vec n a -> String #

showList :: [Vec n a] -> ShowS #

Semigroup a => Semigroup (Vec n a) Source # 
Instance details

Defined in Data.Vec.Lazy

Methods

(<>) :: Vec n a -> Vec n a -> Vec n a #

sconcat :: NonEmpty (Vec n a) -> Vec n a #

stimes :: Integral b => b -> Vec n a -> Vec n a #

(Monoid a, SNatI n) => Monoid (Vec n a) Source # 
Instance details

Defined in Data.Vec.Lazy

Methods

mempty :: Vec n a #

mappend :: Vec n a -> Vec n a -> Vec n a #

mconcat :: [Vec n a] -> Vec n a #

(SNatI n, Function a) => Function (Vec n a) Source # 
Instance details

Defined in Data.Vec.Lazy

Methods

function :: (Vec n a -> b) -> Vec n a :-> b #

(SNatI n, Arbitrary a) => Arbitrary (Vec n a) Source # 
Instance details

Defined in Data.Vec.Lazy

Methods

arbitrary :: Gen (Vec n a) #

shrink :: Vec n a -> [Vec n a] #

(SNatI n, CoArbitrary a) => CoArbitrary (Vec n a) Source # 
Instance details

Defined in Data.Vec.Lazy

Methods

coarbitrary :: Vec n a -> Gen b -> Gen b #

NFData a => NFData (Vec n a) Source # 
Instance details

Defined in Data.Vec.Lazy

Methods

rnf :: Vec n a -> () #

Hashable a => Hashable (Vec n a) Source # 
Instance details

Defined in Data.Vec.Lazy

Methods

hashWithSalt :: Int -> Vec n a -> Int #

hash :: Vec n a -> Int #

type Rep (Vec n) Source # 
Instance details

Defined in Data.Vec.Lazy

type Rep (Vec n) = Fin n

Construction

empty :: Vec Z a Source #

Empty Vec.

singleton :: a -> Vec (S Z) a Source #

Vec with exactly one element.

>>> singleton True
True ::: VNil

withDict :: Vec n a -> (InlineInduction n => r) -> r Source #

O(n). Recover InlineInduction (and SNatI) dictionary from a Vec value.

Example: reflect is constrained with SNatI n, but if we have a Vec n a, we can recover that dictionary:

>>> let f :: forall n a. Vec n a -> N.Nat; f v = withDict v (N.reflect (Proxy :: Proxy n)) in f (True ::: VNil)
1

Note: using InlineInduction will be suboptimal, as if GHC has no opportunity to optimise the code, the recusion won't be unfold. How bad such code will perform? I don't know, we'll need benchmarks.

Conversions

toPull :: Vec n a -> Vec n a Source #

Convert to pull Vec.

fromPull :: forall n a. SNatI n => Vec n a -> Vec n a Source #

Convert from pull Vec.

toList :: Vec n a -> [a] Source #

Convert Vec to list.

>>> toList $ 'f' ::: 'o' ::: 'o' ::: VNil
"foo"

fromList :: SNatI n => [a] -> Maybe (Vec n a) Source #

Convert list [a] to Vec n a. Returns Nothing if lengths don't match exactly.

>>> fromList "foo" :: Maybe (Vec N.Nat3 Char)
Just ('f' ::: 'o' ::: 'o' ::: VNil)
>>> fromList "quux" :: Maybe (Vec N.Nat3 Char)
Nothing
>>> fromList "xy" :: Maybe (Vec N.Nat3 Char)
Nothing

fromListPrefix :: SNatI n => [a] -> Maybe (Vec n a) Source #

Convert list [a] to Vec n a. Returns Nothing if input list is too short.

>>> fromListPrefix "foo" :: Maybe (Vec N.Nat3 Char)
Just ('f' ::: 'o' ::: 'o' ::: VNil)
>>> fromListPrefix "quux" :: Maybe (Vec N.Nat3 Char)
Just ('q' ::: 'u' ::: 'u' ::: VNil)
>>> fromListPrefix "xy" :: Maybe (Vec N.Nat3 Char)
Nothing

reifyList :: [a] -> (forall n. InlineInduction n => Vec n a -> r) -> r Source #

Reify any list [a] to Vec n a.

>>> reifyList "foo" length
3

Indexing

(!) :: Vec n a -> Fin n -> a Source #

Indexing.

>>> ('a' ::: 'b' ::: 'c' ::: VNil) ! FS FZ
'b'

tabulate :: SNatI n => (Fin n -> a) -> Vec n a Source #

Tabulating, inverse of !.

>>> tabulate id :: Vec N.Nat3 (Fin N.Nat3)
0 ::: 1 ::: 2 ::: VNil

cons :: a -> Vec n a -> Vec (S n) a Source #

Cons an element in front of a Vec.

snoc :: Vec n a -> a -> Vec (S n) a Source #

Add a single element at the end of a Vec.

Since: 0.2.1

head :: Vec (S n) a -> a Source #

The first element of a Vec.

tail :: Vec (S n) a -> Vec n a Source #

The elements after the head of a Vec.

Reverse

reverse :: Vec n a -> Vec n a Source #

Reverse Vec.

>>> reverse ('a' ::: 'b' ::: 'c' ::: VNil)
'c' ::: 'b' ::: 'a' ::: VNil

Since: 0.2.1

Concatenation and splitting

(++) :: Vec n a -> Vec m a -> Vec (Plus n m) a infixr 5 Source #

Append two Vec.

>>> ('a' ::: 'b' ::: VNil) ++ ('c' ::: 'd' ::: VNil)
'a' ::: 'b' ::: 'c' ::: 'd' ::: VNil

split :: SNatI n => Vec (Plus n m) a -> (Vec n a, Vec m a) Source #

Split vector into two parts. Inverse of ++.

>>> split ('a' ::: 'b' ::: 'c' ::: VNil) :: (Vec N.Nat1 Char, Vec N.Nat2 Char)
('a' ::: VNil,'b' ::: 'c' ::: VNil)
>>> uncurry (++) (split ('a' ::: 'b' ::: 'c' ::: VNil) :: (Vec N.Nat1 Char, Vec N.Nat2 Char))
'a' ::: 'b' ::: 'c' ::: VNil

concatMap :: (a -> Vec m b) -> Vec n a -> Vec (Mult n m) b Source #

Map over all the elements of a Vec and concatenate the resulting Vecs.

>>> concatMap (\x -> x ::: x ::: VNil) ('a' ::: 'b' ::: VNil)
'a' ::: 'a' ::: 'b' ::: 'b' ::: VNil

concat :: Vec n (Vec m a) -> Vec (Mult n m) a Source #

chunks :: (SNatI n, SNatI m) => Vec (Mult n m) a -> Vec n (Vec m a) Source #

Inverse of concat.

>>> chunks <$> fromListPrefix [1..] :: Maybe (Vec N.Nat2 (Vec N.Nat3 Int))
Just ((1 ::: 2 ::: 3 ::: VNil) ::: (4 ::: 5 ::: 6 ::: VNil) ::: VNil)
>>> let idVec x = x :: Vec N.Nat2 (Vec N.Nat3 Int)
>>> concat . idVec . chunks <$> fromListPrefix [1..]
Just (1 ::: 2 ::: 3 ::: 4 ::: 5 ::: 6 ::: VNil)

Folds

foldMap :: Monoid m => (a -> m) -> Vec n a -> m Source #

foldMap1 :: Semigroup s => (a -> s) -> Vec (S n) a -> s Source #

ifoldMap :: Monoid m => (Fin n -> a -> m) -> Vec n a -> m Source #

ifoldMap1 :: Semigroup s => (Fin (S n) -> a -> s) -> Vec (S n) a -> s Source #

There is no type-class for this :(

foldr :: forall a b n. (a -> b -> b) -> b -> Vec n a -> b Source #

Right fold.

ifoldr :: forall a b n. (Fin n -> a -> b -> b) -> b -> Vec n a -> b Source #

Right fold with an index.

foldl' :: forall a b n. (b -> a -> b) -> b -> Vec n a -> b Source #

Strict left fold.

Special folds

length :: Vec n a -> Int Source #

Yield the length of a Vec. O(n)

null :: Vec n a -> Bool Source #

Test whether a Vec is empty. O(1)

sum :: Num a => Vec n a -> a Source #

Non-strict sum.

product :: Num a => Vec n a -> a Source #

Non-strict product.

Mapping

map :: (a -> b) -> Vec n a -> Vec n b Source #

>>> map not $ True ::: False ::: VNil
False ::: True ::: VNil

imap :: (Fin n -> a -> b) -> Vec n a -> Vec n b Source #

>>> imap (,) $ 'a' ::: 'b' ::: 'c' ::: VNil
(0,'a') ::: (1,'b') ::: (2,'c') ::: VNil

traverse :: forall n f a b. Applicative f => (a -> f b) -> Vec n a -> f (Vec n b) Source #

Apply an action to every element of a Vec, yielding a Vec of results.

traverse1 :: forall n f a b. Apply f => (a -> f b) -> Vec (S n) a -> f (Vec (S n) b) Source #

Apply an action to non-empty Vec, yielding a Vec of results.

itraverse :: Applicative f => (Fin n -> a -> f b) -> Vec n a -> f (Vec n b) Source #

Apply an action to every element of a Vec and its index, yielding a Vec of results.

itraverse_ :: Applicative f => (Fin n -> a -> f b) -> Vec n a -> f () Source #

Apply an action to every element of a Vec and its index, ignoring the results.

Zipping

zipWith :: (a -> b -> c) -> Vec n a -> Vec n b -> Vec n c Source #

Zip two Vecs with a function.

izipWith :: (Fin n -> a -> b -> c) -> Vec n a -> Vec n b -> Vec n c Source #

Zip two Vecs. with a function that also takes the elements' indices.

repeat :: SNatI n => x -> Vec n x Source #

Repeat a value.

>>> repeat 'x' :: Vec N.Nat3 Char
'x' ::: 'x' ::: 'x' ::: VNil

Since: 0.2.1

Monadic

bind :: Vec n a -> (a -> Vec n b) -> Vec n b Source #

Monadic bind.

join :: Vec n (Vec n a) -> Vec n a Source #

Monadic join.

>>> join $ ('a' ::: 'b' ::: VNil) ::: ('c' ::: 'd' ::: VNil) ::: VNil
'a' ::: 'd' ::: VNil

Universe

universe :: SNatI n => Vec n (Fin n) Source #

Get all Fin n in a Vec n.

>>> universe :: Vec N.Nat3 (Fin N.Nat3)
0 ::: 1 ::: 2 ::: VNil

VecEach

class VecEach s t a b | s -> a, t -> b, s b -> t, t a -> s where Source #

Write functions on Vec. Use them with tuples.

VecEach can be used to avoid "this function won't change the length of the list" in DSLs.

bad: Instead of

[x, y] <- badDslMagic ["foo", "bar"]  -- list!

good: we can write

(x, y) <- betterDslMagic ("foo", "bar") -- homogenic tuple!

where betterDslMagic can be defined using traverseWithVec.

Moreally lens Each should be a superclass, but there's no strict need for it.

Methods

mapWithVec :: (forall n. InlineInduction n => Vec n a -> Vec n b) -> s -> t Source #

traverseWithVec :: Applicative f => (forall n. InlineInduction n => Vec n a -> f (Vec n b)) -> s -> f t Source #

Instances
(a ~ a', b ~ b') => VecEach (a, a') (b, b') a b Source # 
Instance details

Defined in Data.Vec.Lazy

Methods

mapWithVec :: (forall (n :: Nat). InlineInduction n => Vec n a -> Vec n b) -> (a, a') -> (b, b') Source #

traverseWithVec :: Applicative f => (forall (n :: Nat). InlineInduction n => Vec n a -> f (Vec n b)) -> (a, a') -> f (b, b') Source #

(a ~ a2, a ~ a3, b ~ b2, b ~ b3) => VecEach (a, a2, a3) (b, b2, b3) a b Source # 
Instance details

Defined in Data.Vec.Lazy

Methods

mapWithVec :: (forall (n :: Nat). InlineInduction n => Vec n a -> Vec n b) -> (a, a2, a3) -> (b, b2, b3) Source #

traverseWithVec :: Applicative f => (forall (n :: Nat). InlineInduction n => Vec n a -> f (Vec n b)) -> (a, a2, a3) -> f (b, b2, b3) Source #

(a ~ a2, a ~ a3, a ~ a4, b ~ b2, b ~ b3, b ~ b4) => VecEach (a, a2, a3, a4) (b, b2, b3, b4) a b Source # 
Instance details

Defined in Data.Vec.Lazy

Methods

mapWithVec :: (forall (n :: Nat). InlineInduction n => Vec n a -> Vec n b) -> (a, a2, a3, a4) -> (b, b2, b3, b4) Source #

traverseWithVec :: Applicative f => (forall (n :: Nat). InlineInduction n => Vec n a -> f (Vec n b)) -> (a, a2, a3, a4) -> f (b, b2, b3, b4) Source #