-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | Vec: length-indexed (sized) list
--   
--   This package provides length-indexed (sized) lists, also known as
--   vectors.
--   
--   <pre>
--   data Vec n a where
--       VNil  :: Vec 'Nat.Z a
--       (:::) :: a -&gt; Vec n a -&gt; Vec ('Nat.S n) a
--   </pre>
--   
--   The functions are implemented in three flavours:
--   
--   <ul>
--   <li><b>naive</b>: with explicit recursion. It's simple,
--   constraint-less, yet slow.</li>
--   <li><b>pull</b>: using <tt>Fin n -&gt; a</tt> representation, which
--   fuses well, but makes some programs hard to write. And</li>
--   <li><b>inline</b>: which exploits how GHC dictionary inlining works,
--   unrolling recursion if the size of <a>Vec</a> is known
--   statically.</li>
--   </ul>
--   
--   As best approach depends on the application, <tt>vec</tt> doesn't do
--   any magic transformation. Benchmark your code.
--   
--   This package uses <a>fin</a>, i.e. not <tt>GHC.TypeLits</tt>, for
--   indexes.
--   
--   See <a>Hasochism: the pleasure and pain of dependently typed haskell
--   programming</a> by Sam Lindley and Conor McBride for answers to
--   <i>how</i> and <i>why</i>. Read <a>APLicative Programming with
--   Naperian Functors</a> by Jeremy Gibbons for (not so) different ones.
--   
--   <h3>Similar packages</h3>
--   
--   <ul>
--   <li><a>linear</a> has <a>V</a> type, which uses <a>Vector</a> from
--   <tt>vector</tt> package as backing store. <tt>Vec</tt> is a real GADT,
--   but tries to provide as many useful instances (upto
--   <tt>lens</tt>).</li>
--   <li><a>vector-sized</a> Great package using <tt>GHC.TypeLits</tt>.
--   Current version (0.6.1.0) uses <tt>finite-typelits</tt> and
--   <tt>Int</tt> indexes.</li>
--   <li><a>sized-vector</a> depends on <tt>singletons</tt> package.
--   <tt>vec</tt> isn't light on dependencies either, but try to provide
--   wide GHC support.</li>
--   <li><a>fixed-vector</a></li>
--   <li><a>sized</a> also depends on a <tt>singletons</tt> package. The
--   <tt>Sized f n a</tt> type is generalisation of <tt>linear</tt>'s
--   <tt>V</tt> for any <tt>ListLike</tt>.</li>
--   <li><a>clash-prelude</a> is a kitchen sink package, which has
--   <tt>CLaSH.Sized.Vector</tt> module. Also depends on
--   <tt>singletons</tt>.</li>
--   </ul>
@package vec
@version 0.1


-- | Pull/representable <tt><a>Vec</a> n a = <a>Fin</a> n -&gt; a</tt>.
--   
--   The module tries to have same API as <a>Data.Vec.Lazy</a>, missing
--   bits: <tt>withDict</tt>, <tt>toPull</tt>, <tt>fromPull</tt>,
--   <tt>traverse</tt> (and variants), <tt>(++)</tt>, <tt>concat</tt> and
--   <tt>split</tt>.
module Data.Vec.Pull

-- | Easily fuseable <a>Vec</a>.
--   
--   It unpurpose don't have <i>bad</i> (fusion-wise) instances, like
--   <tt>Traversable</tt>. Generally, there aren't functions which would be
--   <b>bad consumers</b> or <b>bad producers</b>.
newtype Vec n a
Vec :: Fin n -> a -> Vec n a
[unVec] :: Vec n a -> Fin n -> a

-- | Empty <a>Vec</a>.
empty :: Vec  'Z a

-- | <a>Vec</a> with exactly one element.
--   
--   <pre>
--   &gt;&gt;&gt; L.fromPull $ singleton True
--   True ::: VNil
--   </pre>
singleton :: a -> Vec ( 'S  'Z) a

-- | Convert <a>Vec</a> to list.
toList :: SNatI n => Vec n a -> [a]

-- | Convert list <tt>[a]</tt> to <tt><a>Vec</a> n a</tt>. Returns
--   <a>Nothing</a> if lengths don't match exactly.
--   
--   <pre>
--   &gt;&gt;&gt; L.fromPull &lt;$&gt; fromList "foo" :: Maybe (L.Vec N.Nat3 Char)
--   Just ('f' ::: 'o' ::: 'o' ::: VNil)
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; L.fromPull &lt;$&gt; fromList "quux" :: Maybe (L.Vec N.Nat3 Char)
--   Nothing
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; L.fromPull &lt;$&gt; fromList "xy" :: Maybe (L.Vec N.Nat3 Char)
--   Nothing
--   </pre>
fromList :: SNatI n => [a] -> Maybe (Vec n a)

-- | Prism from list.
_Vec :: SNatI n => Prism' [a] (Vec n a)

-- | Convert list <tt>[a]</tt> to <tt><a>Vec</a> n a</tt>. Returns
--   <a>Nothing</a> if input list is too short.
--   
--   <pre>
--   &gt;&gt;&gt; L.fromPull &lt;$&gt; fromListPrefix "foo" :: Maybe (L.Vec N.Nat3 Char)
--   Just ('f' ::: 'o' ::: 'o' ::: VNil)
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; L.fromPull &lt;$&gt; fromListPrefix "quux" :: Maybe (L.Vec N.Nat3 Char)
--   Just ('q' ::: 'u' ::: 'u' ::: VNil)
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; L.fromPull &lt;$&gt; fromListPrefix "xy" :: Maybe (L.Vec N.Nat3 Char)
--   Nothing
--   </pre>
fromListPrefix :: SNatI n => [a] -> Maybe (Vec n a)

-- | Reify any list <tt>[a]</tt> to <tt><a>Vec</a> n a</tt>.
--   
--   <pre>
--   &gt;&gt;&gt; reifyList "foo" length
--   3
--   </pre>
reifyList :: [a] -> (forall n. InlineInduction n => Vec n a -> r) -> r

-- | Indexing.
(!) :: Vec n a -> Fin n -> a

-- | Index lens.
--   
--   <pre>
--   &gt;&gt;&gt; ('a' L.::: 'b' L.::: 'c' L.::: L.VNil) ^. L._Pull . ix (F.S F.Z)
--   'b'
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; ('a' L.::: 'b' L.::: 'c' L.::: L.VNil) &amp; L._Pull . ix (F.S F.Z) .~ 'x'
--   'a' ::: 'x' ::: 'c' ::: VNil
--   </pre>
ix :: Fin n -> Lens' (Vec n a) a

-- | Match on non-empty <a>Vec</a>.
--   
--   <i>Note:</i> <tt>lens</tt> <a>_Cons</a> is a <a>Prism</a>. In fact,
--   <tt><a>Vec</a> n a</tt> cannot have an instance of <a>Cons</a> as
--   types don't match.
_Cons :: Iso (Vec ( 'S n) a) (Vec ( 'S n) b) (a, Vec n a) (b, Vec n b)

-- | Head lens. <i>Note:</i> <tt>lens</tt> <a>_head</a> is a
--   <a>Traversal'</a>.
--   
--   <pre>
--   &gt;&gt;&gt; ('a' L.::: 'b' L.::: 'c' L.::: L.VNil) ^. L._Pull . _head
--   'a'
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; ('a' L.::: 'b' L.::: 'c' L.::: L.VNil) &amp; L._Pull . _head .~ 'x'
--   'x' ::: 'b' ::: 'c' ::: VNil
--   </pre>
_head :: Lens' (Vec ( 'S n) a) a

-- | Head lens. <i>Note:</i> <tt>lens</tt> <a>_head</a> is a
--   <a>Traversal'</a>.
_tail :: Lens' (Vec ( 'S n) a) (Vec n a)

-- | The first element of a <a>Vec</a>.
head :: Vec ( 'S n) a -> a

-- | The elements after the <a>head</a> of a <a>Vec</a>.
tail :: Vec ( 'S n) a -> Vec n a

-- | See <a>Foldable</a>.
foldMap :: (Monoid m, SNatI n) => (a -> m) -> Vec n a -> m

-- | See <a>Foldable1</a>.
foldMap1 :: (Semigroup s, SNatI n) => (a -> s) -> Vec ( 'S n) a -> s

-- | See <a>FoldableWithIndex</a>.
ifoldMap :: (Monoid m, SNatI n) => (Fin n -> a -> m) -> Vec n a -> m

-- | There is no type-class for this :(
ifoldMap1 :: (Semigroup s, SNatI n) => (Fin ( 'S n) -> a -> s) -> Vec ( 'S n) a -> s

-- | Right fold.
foldr :: SNatI n => (a -> b -> b) -> b -> Vec n a -> b

-- | Right fold with an index.
ifoldr :: SNatI n => (Fin n -> a -> b -> b) -> b -> Vec n a -> b

-- | Strict left fold.
foldl' :: SNatI n => (b -> a -> b) -> b -> Vec n a -> b

-- | Yield the length of a <a>Vec</a>.
length :: forall n a. SNatI n => Vec n a -> Int

-- | Test whether a <a>Vec</a> is empty.
null :: forall n a. SNatI n => Vec n a -> Bool

-- | Strict <a>sum</a>.
sum :: (Num a, SNatI n) => Vec n a -> a

-- | Strict <a>product</a>.
product :: (Num a, SNatI n) => Vec n a -> a

-- | <pre>
--   &gt;&gt;&gt; over L._Pull (map not) (True L.::: False L.::: L.VNil)
--   False ::: True ::: VNil
--   </pre>
map :: (a -> b) -> Vec n a -> Vec n b

-- | <pre>
--   &gt;&gt;&gt; over L._Pull (imap (,)) ('a' L.::: 'b' L.::: 'c' L.::: L.VNil)
--   (0,'a') ::: (1,'b') ::: (2,'c') ::: VNil
--   </pre>
imap :: (Fin n -> a -> b) -> Vec n a -> Vec n b

-- | Zip two <a>Vec</a>s with a function.
zipWith :: (a -> b -> c) -> Vec n a -> Vec n b -> Vec n c

-- | Zip two <a>Vec</a>s. with a function that also takes the elements'
--   indices.
izipWith :: (Fin n -> a -> b -> c) -> Vec n a -> Vec n b -> Vec n c

-- | Monadic bind.
bind :: Vec n a -> (a -> Vec n b) -> Vec n b

-- | Monadic join.
join :: Vec n (Vec n a) -> Vec n a

-- | Get all <tt><a>Fin</a> n</tt> in a <tt><a>Vec</a> n</tt>.
--   
--   <pre>
--   &gt;&gt;&gt; L.fromPull (universe :: Vec N.Nat3 (Fin N.Nat3))
--   0 ::: 1 ::: 2 ::: VNil
--   </pre>
universe :: SNatI n => Vec n (Fin n)
instance (GHC.Classes.Eq a, Data.Type.Nat.SNatI n) => GHC.Classes.Eq (Data.Vec.Pull.Vec n a)
instance GHC.Base.Functor (Data.Vec.Pull.Vec n)
instance Data.Type.Nat.SNatI n => Data.Foldable.Foldable (Data.Vec.Pull.Vec n)
instance GHC.Base.Applicative (Data.Vec.Pull.Vec n)
instance GHC.Base.Monad (Data.Vec.Pull.Vec n)
instance Data.Distributive.Distributive (Data.Vec.Pull.Vec n)
instance Data.Functor.Rep.Representable (Data.Vec.Pull.Vec n)
instance GHC.Base.Semigroup a => GHC.Base.Semigroup (Data.Vec.Pull.Vec n a)
instance GHC.Base.Monoid a => GHC.Base.Monoid (Data.Vec.Pull.Vec n a)
instance Data.Functor.Bind.Class.Apply (Data.Vec.Pull.Vec n)
instance Data.Functor.Bind.Class.Bind (Data.Vec.Pull.Vec n)
instance Control.Lens.Indexed.FunctorWithIndex (Data.Fin.Fin n) (Data.Vec.Pull.Vec n)
instance Data.Type.Nat.SNatI n => Control.Lens.Indexed.FoldableWithIndex (Data.Fin.Fin n) (Data.Vec.Pull.Vec n)


-- | Lazy length-indexed list: <a>Vec</a>.
module Data.Vec.Lazy

-- | Vector, i.e. length-indexed list.
data Vec (n :: Nat) a
[VNil] :: Vec  'Z a
[:::] :: a -> Vec n a -> Vec ( 'S n) a

-- | Empty <a>Vec</a>.
empty :: Vec  'Z a

-- | <a>Vec</a> with exactly one element.
--   
--   <pre>
--   &gt;&gt;&gt; singleton True
--   True ::: VNil
--   </pre>
singleton :: a -> Vec ( 'S  'Z) a

-- | <i>O(n)</i>. Recover <a>InlineInduction</a> (and <a>SNatI</a>)
--   dictionary from a <a>Vec</a> value.
--   
--   Example: <a>reflect</a> is constrained with <tt><a>SNatI</a> n</tt>,
--   but if we have a <tt><a>Vec</a> n a</tt>, we can recover that
--   dictionary:
--   
--   <pre>
--   &gt;&gt;&gt; let f :: forall n a. Vec n a -&gt; N.Nat; f v = withDict v (N.reflect (Proxy :: Proxy n)) in f (True ::: VNil)
--   1
--   </pre>
--   
--   <i>Note:</i> using <a>InlineInduction</a> 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.
withDict :: Vec n a -> (InlineInduction n => r) -> r

-- | Convert to pull <a>Vec</a>.
toPull :: Vec n a -> Vec n a

-- | Convert from pull <a>Vec</a>.
fromPull :: forall n a. SNatI n => Vec n a -> Vec n a

-- | An <a>Iso</a> from <a>toPull</a> and <a>fromPull</a>.
_Pull :: SNatI n => Iso (Vec n a) (Vec n b) (Vec n a) (Vec n b)

-- | Convert <a>Vec</a> to list.
--   
--   <pre>
--   &gt;&gt;&gt; toList $ 'f' ::: 'o' ::: 'o' ::: VNil
--   "foo"
--   </pre>
toList :: Vec n a -> [a]

-- | Convert list <tt>[a]</tt> to <tt><a>Vec</a> n a</tt>. Returns
--   <a>Nothing</a> if lengths don't match exactly.
--   
--   <pre>
--   &gt;&gt;&gt; fromList "foo" :: Maybe (Vec N.Nat3 Char)
--   Just ('f' ::: 'o' ::: 'o' ::: VNil)
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; fromList "quux" :: Maybe (Vec N.Nat3 Char)
--   Nothing
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; fromList "xy" :: Maybe (Vec N.Nat3 Char)
--   Nothing
--   </pre>
fromList :: SNatI n => [a] -> Maybe (Vec n a)

-- | Prism from list.
--   
--   <pre>
--   &gt;&gt;&gt; "foo" ^? _Vec :: Maybe (Vec N.Nat3 Char)
--   Just ('f' ::: 'o' ::: 'o' ::: VNil)
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; "foo" ^? _Vec :: Maybe (Vec N.Nat2 Char)
--   Nothing
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; _Vec # (True ::: False ::: VNil)
--   [True,False]
--   </pre>
_Vec :: SNatI n => Prism' [a] (Vec n a)

-- | Convert list <tt>[a]</tt> to <tt><a>Vec</a> n a</tt>. Returns
--   <a>Nothing</a> if input list is too short.
--   
--   <pre>
--   &gt;&gt;&gt; fromListPrefix "foo" :: Maybe (Vec N.Nat3 Char)
--   Just ('f' ::: 'o' ::: 'o' ::: VNil)
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; fromListPrefix "quux" :: Maybe (Vec N.Nat3 Char)
--   Just ('q' ::: 'u' ::: 'u' ::: VNil)
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; fromListPrefix "xy" :: Maybe (Vec N.Nat3 Char)
--   Nothing
--   </pre>
fromListPrefix :: SNatI n => [a] -> Maybe (Vec n a)

-- | Reify any list <tt>[a]</tt> to <tt><a>Vec</a> n a</tt>.
--   
--   <pre>
--   &gt;&gt;&gt; reifyList "foo" length
--   3
--   </pre>
reifyList :: [a] -> (forall n. InlineInduction n => Vec n a -> r) -> r

-- | Indexing.
--   
--   <pre>
--   &gt;&gt;&gt; ('a' ::: 'b' ::: 'c' ::: VNil) ! F.S F.Z
--   'b'
--   </pre>
(!) :: Vec n a -> Fin n -> a

-- | Index lens.
--   
--   <pre>
--   &gt;&gt;&gt; ('a' ::: 'b' ::: 'c' ::: VNil) ^. ix (F.S F.Z)
--   'b'
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; ('a' ::: 'b' ::: 'c' ::: VNil) &amp; ix (F.S F.Z) .~ 'x'
--   'a' ::: 'x' ::: 'c' ::: VNil
--   </pre>
ix :: Fin n -> Lens' (Vec n a) a

-- | Match on non-empty <a>Vec</a>.
--   
--   <i>Note:</i> <tt>lens</tt> <a>_Cons</a> is a <a>Prism</a>. In fact,
--   <tt><a>Vec</a> n a</tt> cannot have an instance of <a>Cons</a> as
--   types don't match.
_Cons :: Iso (Vec ( 'S n) a) (Vec ( 'S n) b) (a, Vec n a) (b, Vec n b)

-- | Head lens. <i>Note:</i> <tt>lens</tt> <a>_head</a> is a
--   <a>Traversal'</a>.
--   
--   <pre>
--   &gt;&gt;&gt; ('a' ::: 'b' ::: 'c' ::: VNil) ^. _head
--   'a'
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; ('a' ::: 'b' ::: 'c' ::: VNil) &amp; _head .~ 'x'
--   'x' ::: 'b' ::: 'c' ::: VNil
--   </pre>
_head :: Lens' (Vec ( 'S n) a) a

-- | Head lens. <i>Note:</i> <tt>lens</tt> <a>_head</a> is a
--   <a>Traversal'</a>.
_tail :: Lens' (Vec ( 'S n) a) (Vec n a)

-- | Cons an element in front of a <a>Vec</a>.
cons :: a -> Vec n a -> Vec ( 'S n) a

-- | The first element of a <a>Vec</a>.
head :: Vec ( 'S n) a -> a

-- | The elements after the <a>head</a> of a <a>Vec</a>.
tail :: Vec ( 'S n) a -> Vec n a

-- | Append two <a>Vec</a>.
--   
--   <pre>
--   &gt;&gt;&gt; ('a' ::: 'b' ::: VNil) ++ ('c' ::: 'd' ::: VNil)
--   'a' ::: 'b' ::: 'c' ::: 'd' ::: VNil
--   </pre>
(++) :: Vec n a -> Vec m a -> Vec (Plus n m) a
infixr 5 ++

-- | Split vector into two parts. Inverse of <a>++</a>.
--   
--   <pre>
--   &gt;&gt;&gt; split ('a' ::: 'b' ::: 'c' ::: VNil) :: (Vec N.Nat1 Char, Vec N.Nat2 Char)
--   ('a' ::: VNil,'b' ::: 'c' ::: VNil)
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; uncurry (++) (split ('a' ::: 'b' ::: 'c' ::: VNil) :: (Vec N.Nat1 Char, Vec N.Nat2 Char))
--   'a' ::: 'b' ::: 'c' ::: VNil
--   </pre>
split :: SNatI n => Vec (Plus n m) a -> (Vec n a, Vec m a)

-- | Map over all the elements of a <a>Vec</a> and concatenate the
--   resulting <a>Vec</a>s.
--   
--   <pre>
--   &gt;&gt;&gt; concatMap (\x -&gt; x ::: x ::: VNil) ('a' ::: 'b' ::: VNil)
--   'a' ::: 'a' ::: 'b' ::: 'b' ::: VNil
--   </pre>
concatMap :: (a -> Vec m b) -> Vec n a -> Vec (Mult n m) b

-- | <pre>
--   <a>concatMap</a> <a>id</a>
--   </pre>
concat :: Vec n (Vec m a) -> Vec (Mult n m) a

-- | Inverse of <a>concat</a>.
--   
--   <pre>
--   &gt;&gt;&gt; chunks &lt;$&gt; fromListPrefix [1..] :: Maybe (Vec N.Nat2 (Vec N.Nat3 Int))
--   Just ((1 ::: 2 ::: 3 ::: VNil) ::: (4 ::: 5 ::: 6 ::: VNil) ::: VNil)
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; let idVec x = x :: Vec N.Nat2 (Vec N.Nat3 Int)
--   
--   &gt;&gt;&gt; concat . idVec . chunks &lt;$&gt; fromListPrefix [1..]
--   Just (1 ::: 2 ::: 3 ::: 4 ::: 5 ::: 6 ::: VNil)
--   </pre>
chunks :: (SNatI n, SNatI m) => Vec (Mult n m) a -> Vec n (Vec m a)

-- | See <a>Foldable</a>.
foldMap :: Monoid m => (a -> m) -> Vec n a -> m

-- | See <a>Foldable1</a>.
foldMap1 :: Semigroup s => (a -> s) -> Vec ( 'S n) a -> s

-- | See <a>FoldableWithIndex</a>.
ifoldMap :: Monoid m => (Fin n -> a -> m) -> Vec n a -> m

-- | There is no type-class for this :(
ifoldMap1 :: Semigroup s => (Fin ( 'S n) -> a -> s) -> Vec ( 'S n) a -> s

-- | Right fold.
foldr :: forall a b n. (a -> b -> b) -> b -> Vec n a -> b

-- | Right fold with an index.
ifoldr :: forall a b n. (Fin n -> a -> b -> b) -> b -> Vec n a -> b

-- | Strict left fold.
foldl' :: forall a b n. (b -> a -> b) -> b -> Vec n a -> b

-- | Yield the length of a <a>Vec</a>. <i>O(n)</i>
length :: Vec n a -> Int

-- | Test whether a <a>Vec</a> is empty. <i>O(1)</i>
null :: Vec n a -> Bool

-- | Non-strict <a>sum</a>.
sum :: Num a => Vec n a -> a

-- | Non-strict <a>product</a>.
product :: Num a => Vec n a -> a

-- | <pre>
--   &gt;&gt;&gt; map not $ True ::: False ::: VNil
--   False ::: True ::: VNil
--   </pre>
map :: (a -> b) -> Vec n a -> Vec n b

-- | <pre>
--   &gt;&gt;&gt; imap (,) $ 'a' ::: 'b' ::: 'c' ::: VNil
--   (0,'a') ::: (1,'b') ::: (2,'c') ::: VNil
--   </pre>
imap :: (Fin n -> a -> b) -> Vec n a -> Vec n b

-- | Apply an action to every element of a <a>Vec</a>, yielding a
--   <a>Vec</a> of results.
traverse :: forall n f a b. Applicative f => (a -> f b) -> Vec n a -> f (Vec n b)

-- | Apply an action to non-empty <a>Vec</a>, yielding a <a>Vec</a> of
--   results.
traverse1 :: forall n f a b. Apply f => (a -> f b) -> Vec ( 'S n) a -> f (Vec ( 'S n) b)

-- | Apply an action to every element of a <a>Vec</a> and its index,
--   yielding a <a>Vec</a> of results.
itraverse :: Applicative f => (Fin n -> a -> f b) -> Vec n a -> f (Vec n b)

-- | Apply an action to every element of a <a>Vec</a> and its index,
--   ignoring the results.
itraverse_ :: Applicative f => (Fin n -> a -> f b) -> Vec n a -> f ()

-- | Zip two <a>Vec</a>s with a function.
zipWith :: (a -> b -> c) -> Vec n a -> Vec n b -> Vec n c

-- | Zip two <a>Vec</a>s. with a function that also takes the elements'
--   indices.
izipWith :: (Fin n -> a -> b -> c) -> Vec n a -> Vec n b -> Vec n c

-- | Monadic bind.
bind :: Vec n a -> (a -> Vec n b) -> Vec n b

-- | Monadic join.
--   
--   <pre>
--   &gt;&gt;&gt; join $ ('a' ::: 'b' ::: VNil) ::: ('c' ::: 'd' ::: VNil) ::: VNil
--   'a' ::: 'd' ::: VNil
--   </pre>
join :: Vec n (Vec n a) -> Vec n a

-- | Get all <tt><a>Fin</a> n</tt> in a <tt><a>Vec</a> n</tt>.
--   
--   <pre>
--   &gt;&gt;&gt; universe :: Vec N.Nat3 (Fin N.Nat3)
--   0 ::: 1 ::: 2 ::: VNil
--   </pre>
universe :: SNatI n => Vec n (Fin n)

-- | Write functions on <a>Vec</a>. Use them with tuples.
--   
--   <a>VecEach</a> can be used to avoid "this function won't change the
--   length of the list" in DSLs.
--   
--   <b>bad:</b> Instead of
--   
--   <pre>
--   [x, y] &lt;- badDslMagic ["foo", "bar"]  -- list!
--   </pre>
--   
--   <b>good:</b> we can write
--   
--   <pre>
--   (x, y) &lt;- betterDslMagic ("foo", "bar") -- homogenic tuple!
--   </pre>
--   
--   where <tt>betterDslMagic</tt> can be defined using
--   <a>traverseWithVec</a>.
class Each s t a b => VecEach s t a b | s -> a, t -> b, s b -> t, t a -> s
mapWithVec :: VecEach s t a b => (forall n. InlineInduction n => Vec n a -> Vec n b) -> s -> t
traverseWithVec :: (VecEach s t a b, Applicative f) => (forall n. InlineInduction n => Vec n a -> f (Vec n b)) -> s -> f t
instance GHC.Classes.Eq a => GHC.Classes.Eq (Data.Vec.Lazy.Vec n a)
instance GHC.Classes.Ord a => GHC.Classes.Ord (Data.Vec.Lazy.Vec n a)
instance (a ~ a', b ~ b') => Data.Vec.Lazy.VecEach (a, a') (b, b') a b
instance (a ~ a2, a ~ a3, b ~ b2, b ~ b3) => Data.Vec.Lazy.VecEach (a, a2, a3) (b, b2, b3) a b
instance (a ~ a2, a ~ a3, a ~ a4, b ~ b2, b ~ b3, b ~ b4) => Data.Vec.Lazy.VecEach (a, a2, a3, a4) (b, b2, b3, b4) a b
instance GHC.Show.Show a => GHC.Show.Show (Data.Vec.Lazy.Vec n a)
instance GHC.Base.Functor (Data.Vec.Lazy.Vec n)
instance Data.Foldable.Foldable (Data.Vec.Lazy.Vec n)
instance (n ~ 'Data.Nat.S m) => Data.Semigroup.Foldable.Class.Foldable1 (Data.Vec.Lazy.Vec n)
instance Data.Traversable.Traversable (Data.Vec.Lazy.Vec n)
instance (n ~ 'Data.Nat.S m) => Data.Semigroup.Traversable.Class.Traversable1 (Data.Vec.Lazy.Vec n)
instance Control.DeepSeq.NFData a => Control.DeepSeq.NFData (Data.Vec.Lazy.Vec n a)
instance Data.Hashable.Class.Hashable a => Data.Hashable.Class.Hashable (Data.Vec.Lazy.Vec n a)
instance Data.Type.Nat.SNatI n => GHC.Base.Applicative (Data.Vec.Lazy.Vec n)
instance Data.Type.Nat.SNatI n => GHC.Base.Monad (Data.Vec.Lazy.Vec n)
instance Data.Type.Nat.SNatI n => Data.Distributive.Distributive (Data.Vec.Lazy.Vec n)
instance Data.Type.Nat.SNatI n => Data.Functor.Rep.Representable (Data.Vec.Lazy.Vec n)
instance GHC.Base.Semigroup a => GHC.Base.Semigroup (Data.Vec.Lazy.Vec n a)
instance (GHC.Base.Monoid a, Data.Type.Nat.SNatI n) => GHC.Base.Monoid (Data.Vec.Lazy.Vec n a)
instance Data.Functor.Bind.Class.Apply (Data.Vec.Lazy.Vec n)
instance Data.Functor.Bind.Class.Bind (Data.Vec.Lazy.Vec n)
instance Control.Lens.Indexed.FunctorWithIndex (Data.Fin.Fin n) (Data.Vec.Lazy.Vec n)
instance Control.Lens.Indexed.FoldableWithIndex (Data.Fin.Fin n) (Data.Vec.Lazy.Vec n)
instance Control.Lens.Indexed.TraversableWithIndex (Data.Fin.Fin n) (Data.Vec.Lazy.Vec n)
instance Control.Lens.Each.Each (Data.Vec.Lazy.Vec n a) (Data.Vec.Lazy.Vec n b) a b
instance Control.Lens.At.Ixed (Data.Vec.Lazy.Vec n a)
instance Control.Lens.Tuple.Field1 (Data.Vec.Lazy.Vec ('Data.Nat.S n) a) (Data.Vec.Lazy.Vec ('Data.Nat.S n) a) a a
instance Control.Lens.Tuple.Field2 (Data.Vec.Lazy.Vec ('Data.Nat.S ('Data.Nat.S n)) a) (Data.Vec.Lazy.Vec ('Data.Nat.S ('Data.Nat.S n)) a) a a
instance Control.Lens.Tuple.Field3 (Data.Vec.Lazy.Vec ('Data.Nat.S ('Data.Nat.S ('Data.Nat.S n))) a) (Data.Vec.Lazy.Vec ('Data.Nat.S ('Data.Nat.S ('Data.Nat.S n))) a) a a
instance Control.Lens.Tuple.Field4 (Data.Vec.Lazy.Vec ('Data.Nat.S ('Data.Nat.S ('Data.Nat.S ('Data.Nat.S n)))) a) (Data.Vec.Lazy.Vec ('Data.Nat.S ('Data.Nat.S ('Data.Nat.S ('Data.Nat.S n)))) a) a a
instance Control.Lens.Tuple.Field5 (Data.Vec.Lazy.Vec ('Data.Nat.S ('Data.Nat.S ('Data.Nat.S ('Data.Nat.S ('Data.Nat.S n))))) a) (Data.Vec.Lazy.Vec ('Data.Nat.S ('Data.Nat.S ('Data.Nat.S ('Data.Nat.S ('Data.Nat.S n))))) a) a a
instance Control.Lens.Tuple.Field6 (Data.Vec.Lazy.Vec ('Data.Nat.S ('Data.Nat.S ('Data.Nat.S ('Data.Nat.S ('Data.Nat.S ('Data.Nat.S n)))))) a) (Data.Vec.Lazy.Vec ('Data.Nat.S ('Data.Nat.S ('Data.Nat.S ('Data.Nat.S ('Data.Nat.S ('Data.Nat.S n)))))) a) a a
instance Control.Lens.Tuple.Field7 (Data.Vec.Lazy.Vec ('Data.Nat.S ('Data.Nat.S ('Data.Nat.S ('Data.Nat.S ('Data.Nat.S ('Data.Nat.S ('Data.Nat.S n))))))) a) (Data.Vec.Lazy.Vec ('Data.Nat.S ('Data.Nat.S ('Data.Nat.S ('Data.Nat.S ('Data.Nat.S ('Data.Nat.S ('Data.Nat.S n))))))) a) a a
instance Control.Lens.Tuple.Field8 (Data.Vec.Lazy.Vec ('Data.Nat.S ('Data.Nat.S ('Data.Nat.S ('Data.Nat.S ('Data.Nat.S ('Data.Nat.S ('Data.Nat.S ('Data.Nat.S n)))))))) a) (Data.Vec.Lazy.Vec ('Data.Nat.S ('Data.Nat.S ('Data.Nat.S ('Data.Nat.S ('Data.Nat.S ('Data.Nat.S ('Data.Nat.S ('Data.Nat.S n)))))))) a) a a
instance Control.Lens.Tuple.Field9 (Data.Vec.Lazy.Vec ('Data.Nat.S ('Data.Nat.S ('Data.Nat.S ('Data.Nat.S ('Data.Nat.S ('Data.Nat.S ('Data.Nat.S ('Data.Nat.S ('Data.Nat.S n))))))))) a) (Data.Vec.Lazy.Vec ('Data.Nat.S ('Data.Nat.S ('Data.Nat.S ('Data.Nat.S ('Data.Nat.S ('Data.Nat.S ('Data.Nat.S ('Data.Nat.S ('Data.Nat.S n))))))))) a) a a


-- | A variant of <a>Data.Vec.Lazy</a> with functions written using
--   <a>InlineInduction</a>. The hypothesis is that these (goursive)
--   functions could be fully unrolled, if the <a>Vec</a> size <tt>n</tt>
--   is known at compile time.
--   
--   The module has the same API as <a>Data.Vec.Lazy</a> (sans
--   <a>withDict</a> and <tt>foldl'</tt>). <i>Note:</i> instance methods
--   aren't changed, the <a>Vec</a> type is the same.
module Data.Vec.Lazy.Inline

-- | Vector, i.e. length-indexed list.
data Vec (n :: Nat) a
[VNil] :: Vec  'Z a
[:::] :: a -> Vec n a -> Vec ( 'S n) a

-- | Empty <a>Vec</a>.
empty :: Vec  'Z a

-- | <a>Vec</a> with exactly one element.
--   
--   <pre>
--   &gt;&gt;&gt; singleton True
--   True ::: VNil
--   </pre>
singleton :: a -> Vec ( 'S  'Z) a

-- | Convert to pull <a>Vec</a>.
toPull :: forall n a. InlineInduction n => Vec n a -> Vec n a

-- | Convert from pull <a>Vec</a>.
fromPull :: forall n a. InlineInduction n => Vec n a -> Vec n a

-- | An <a>Iso</a> from <a>toPull</a> and <a>fromPull</a>.
_Pull :: InlineInduction n => Iso (Vec n a) (Vec n b) (Vec n a) (Vec n b)

-- | Convert <a>Vec</a> to list.
--   
--   <pre>
--   &gt;&gt;&gt; toList $ 'f' ::: 'o' ::: 'o' ::: VNil
--   "foo"
--   </pre>
toList :: forall n a. InlineInduction n => Vec n a -> [a]

-- | Convert list <tt>[a]</tt> to <tt><a>Vec</a> n a</tt>. Returns
--   <a>Nothing</a> if lengths don't match exactly.
--   
--   <pre>
--   &gt;&gt;&gt; fromList "foo" :: Maybe (Vec N.Nat3 Char)
--   Just ('f' ::: 'o' ::: 'o' ::: VNil)
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; fromList "quux" :: Maybe (Vec N.Nat3 Char)
--   Nothing
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; fromList "xy" :: Maybe (Vec N.Nat3 Char)
--   Nothing
--   </pre>
fromList :: InlineInduction n => [a] -> Maybe (Vec n a)

-- | Prism from list.
--   
--   <pre>
--   &gt;&gt;&gt; "foo" ^? _Vec :: Maybe (Vec N.Nat3 Char)
--   Just ('f' ::: 'o' ::: 'o' ::: VNil)
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; "foo" ^? _Vec :: Maybe (Vec N.Nat2 Char)
--   Nothing
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; _Vec # (True ::: False ::: VNil)
--   [True,False]
--   </pre>
_Vec :: InlineInduction n => Prism' [a] (Vec n a)

-- | Convert list <tt>[a]</tt> to <tt><a>Vec</a> n a</tt>. Returns
--   <a>Nothing</a> if input list is too short.
--   
--   <pre>
--   &gt;&gt;&gt; fromListPrefix "foo" :: Maybe (Vec N.Nat3 Char)
--   Just ('f' ::: 'o' ::: 'o' ::: VNil)
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; fromListPrefix "quux" :: Maybe (Vec N.Nat3 Char)
--   Just ('q' ::: 'u' ::: 'u' ::: VNil)
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; fromListPrefix "xy" :: Maybe (Vec N.Nat3 Char)
--   Nothing
--   </pre>
fromListPrefix :: InlineInduction n => [a] -> Maybe (Vec n a)

-- | Reify any list <tt>[a]</tt> to <tt><a>Vec</a> n a</tt>.
--   
--   <pre>
--   &gt;&gt;&gt; reifyList "foo" length
--   3
--   </pre>
reifyList :: [a] -> (forall n. InlineInduction n => Vec n a -> r) -> r

-- | Indexing.
--   
--   <pre>
--   &gt;&gt;&gt; ('a' ::: 'b' ::: 'c' ::: VNil) ! F.S F.Z
--   'b'
--   </pre>
(!) :: InlineInduction n => Vec n a -> Fin n -> a

-- | Index lens.
--   
--   <pre>
--   &gt;&gt;&gt; ('a' ::: 'b' ::: 'c' ::: VNil) ^. ix (F.S F.Z)
--   'b'
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; ('a' ::: 'b' ::: 'c' ::: VNil) &amp; ix (F.S F.Z) .~ 'x'
--   'a' ::: 'x' ::: 'c' ::: VNil
--   </pre>
ix :: InlineInduction n => Fin n -> Lens' (Vec n a) a

-- | Match on non-empty <a>Vec</a>.
--   
--   <i>Note:</i> <tt>lens</tt> <a>_Cons</a> is a <a>Prism</a>. In fact,
--   <tt><a>Vec</a> n a</tt> cannot have an instance of <a>Cons</a> as
--   types don't match.
_Cons :: Iso (Vec ( 'S n) a) (Vec ( 'S n) b) (a, Vec n a) (b, Vec n b)

-- | Head lens. <i>Note:</i> <tt>lens</tt> <a>_head</a> is a
--   <a>Traversal'</a>.
--   
--   <pre>
--   &gt;&gt;&gt; ('a' ::: 'b' ::: 'c' ::: VNil) ^. _head
--   'a'
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; ('a' ::: 'b' ::: 'c' ::: VNil) &amp; _head .~ 'x'
--   'x' ::: 'b' ::: 'c' ::: VNil
--   </pre>
_head :: Lens' (Vec ( 'S n) a) a

-- | Head lens. <i>Note:</i> <tt>lens</tt> <a>_head</a> is a
--   <a>Traversal'</a>.
_tail :: Lens' (Vec ( 'S n) a) (Vec n a)

-- | Cons an element in front of a <a>Vec</a>.
cons :: a -> Vec n a -> Vec ( 'S n) a

-- | The first element of a <a>Vec</a>.
head :: Vec ( 'S n) a -> a

-- | The elements after the <a>head</a> of a <a>Vec</a>.
tail :: Vec ( 'S n) a -> Vec n a

-- | Append two <a>Vec</a>.
--   
--   <pre>
--   &gt;&gt;&gt; ('a' ::: 'b' ::: VNil) ++ ('c' ::: 'd' ::: VNil)
--   'a' ::: 'b' ::: 'c' ::: 'd' ::: VNil
--   </pre>
(++) :: forall n m a. InlineInduction n => Vec n a -> Vec m a -> Vec (Plus n m) a
infixr 5 ++

-- | Split vector into two parts. Inverse of <a>++</a>.
--   
--   <pre>
--   &gt;&gt;&gt; split ('a' ::: 'b' ::: 'c' ::: VNil) :: (Vec N.Nat1 Char, Vec N.Nat2 Char)
--   ('a' ::: VNil,'b' ::: 'c' ::: VNil)
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; uncurry (++) (split ('a' ::: 'b' ::: 'c' ::: VNil) :: (Vec N.Nat1 Char, Vec N.Nat2 Char))
--   'a' ::: 'b' ::: 'c' ::: VNil
--   </pre>
split :: InlineInduction n => Vec (Plus n m) a -> (Vec n a, Vec m a)

-- | Map over all the elements of a <a>Vec</a> and concatenate the
--   resulting <a>Vec</a>s.
--   
--   <pre>
--   &gt;&gt;&gt; concatMap (\x -&gt; x ::: x ::: VNil) ('a' ::: 'b' ::: VNil)
--   'a' ::: 'a' ::: 'b' ::: 'b' ::: VNil
--   </pre>
concatMap :: forall a b n m. (InlineInduction m, InlineInduction n) => (a -> Vec m b) -> Vec n a -> Vec (Mult n m) b

-- | <pre>
--   <a>concatMap</a> <a>id</a>
--   </pre>
concat :: (InlineInduction m, InlineInduction n) => Vec n (Vec m a) -> Vec (Mult n m) a

-- | Inverse of <a>concat</a>.
--   
--   <pre>
--   &gt;&gt;&gt; chunks &lt;$&gt; fromListPrefix [1..] :: Maybe (Vec N.Nat2 (Vec N.Nat3 Int))
--   Just ((1 ::: 2 ::: 3 ::: VNil) ::: (4 ::: 5 ::: 6 ::: VNil) ::: VNil)
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; let idVec x = x :: Vec N.Nat2 (Vec N.Nat3 Int)
--   
--   &gt;&gt;&gt; concat . idVec . chunks &lt;$&gt; fromListPrefix [1..]
--   Just (1 ::: 2 ::: 3 ::: 4 ::: 5 ::: 6 ::: VNil)
--   </pre>
chunks :: (InlineInduction n, InlineInduction m) => Vec (Mult n m) a -> Vec n (Vec m a)

-- | See <a>Foldable</a>.
foldMap :: (Monoid m, InlineInduction n) => (a -> m) -> Vec n a -> m

-- | See <a>Foldable1</a>.
foldMap1 :: forall s a n. (Semigroup s, InlineInduction n) => (a -> s) -> Vec ( 'S n) a -> s

-- | See <a>FoldableWithIndex</a>.
ifoldMap :: forall a n m. (Monoid m, InlineInduction n) => (Fin n -> a -> m) -> Vec n a -> m

-- | There is no type-class for this :(
ifoldMap1 :: forall a n s. (Semigroup s, InlineInduction n) => (Fin ( 'S n) -> a -> s) -> Vec ( 'S n) a -> s

-- | Right fold.
foldr :: forall a b n. InlineInduction n => (a -> b -> b) -> b -> Vec n a -> b

-- | Right fold with an index.
ifoldr :: forall a b n. InlineInduction n => (Fin n -> a -> b -> b) -> b -> Vec n a -> b

-- | Yield the length of a <a>Vec</a>. <i>O(n)</i>
length :: forall n a. InlineInduction n => Vec n a -> Int

-- | Test whether a <a>Vec</a> is empty. <i>O(1)</i>
null :: Vec n a -> Bool

-- | Non-strict <a>sum</a>.
sum :: (Num a, InlineInduction n) => Vec n a -> a

-- | Non-strict <a>product</a>.
product :: (Num a, InlineInduction n) => Vec n a -> a

-- | <pre>
--   &gt;&gt;&gt; map not $ True ::: False ::: VNil
--   False ::: True ::: VNil
--   </pre>
map :: forall a b n. InlineInduction n => (a -> b) -> Vec n a -> Vec n b

-- | <pre>
--   &gt;&gt;&gt; imap (,) $ 'a' ::: 'b' ::: 'c' ::: VNil
--   (0,'a') ::: (1,'b') ::: (2,'c') ::: VNil
--   </pre>
imap :: InlineInduction n => (Fin n -> a -> b) -> Vec n a -> Vec n b

-- | Apply an action to every element of a <a>Vec</a>, yielding a
--   <a>Vec</a> of results.
traverse :: forall n f a b. (Applicative f, InlineInduction n) => (a -> f b) -> Vec n a -> f (Vec n b)

-- | Apply an action to non-empty <a>Vec</a>, yielding a <a>Vec</a> of
--   results.
traverse1 :: forall n f a b. (Apply f, InlineInduction n) => (a -> f b) -> Vec ( 'S n) a -> f (Vec ( 'S n) b)

-- | Apply an action to every element of a <a>Vec</a> and its index,
--   yielding a <a>Vec</a> of results.
itraverse :: forall n f a b. (Applicative f, InlineInduction n) => (Fin n -> a -> f b) -> Vec n a -> f (Vec n b)

-- | Apply an action to every element of a <a>Vec</a> and its index,
--   ignoring the results.
itraverse_ :: forall n f a b. (Applicative f, InlineInduction n) => (Fin n -> a -> f b) -> Vec n a -> f ()

-- | Zip two <a>Vec</a>s with a function.
zipWith :: forall a b c n. InlineInduction n => (a -> b -> c) -> Vec n a -> Vec n b -> Vec n c

-- | Zip two <a>Vec</a>s. with a function that also takes the elements'
--   indices.
izipWith :: InlineInduction n => (Fin n -> a -> b -> c) -> Vec n a -> Vec n b -> Vec n c

-- | Monadic bind.
bind :: InlineInduction n => Vec n a -> (a -> Vec n b) -> Vec n b

-- | Monadic join.
--   
--   <pre>
--   &gt;&gt;&gt; join $ ('a' ::: 'b' ::: VNil) ::: ('c' ::: 'd' ::: VNil) ::: VNil
--   'a' ::: 'd' ::: VNil
--   </pre>
join :: InlineInduction n => Vec n (Vec n a) -> Vec n a

-- | Get all <tt><a>Fin</a> n</tt> in a <tt><a>Vec</a> n</tt>.
--   
--   <pre>
--   &gt;&gt;&gt; universe :: Vec N.Nat3 (Fin N.Nat3)
--   0 ::: 1 ::: 2 ::: VNil
--   </pre>
universe :: InlineInduction n => Vec n (Fin n)

-- | Write functions on <a>Vec</a>. Use them with tuples.
--   
--   <a>VecEach</a> can be used to avoid "this function won't change the
--   length of the list" in DSLs.
--   
--   <b>bad:</b> Instead of
--   
--   <pre>
--   [x, y] &lt;- badDslMagic ["foo", "bar"]  -- list!
--   </pre>
--   
--   <b>good:</b> we can write
--   
--   <pre>
--   (x, y) &lt;- betterDslMagic ("foo", "bar") -- homogenic tuple!
--   </pre>
--   
--   where <tt>betterDslMagic</tt> can be defined using
--   <a>traverseWithVec</a>.
class Each s t a b => VecEach s t a b | s -> a, t -> b, s b -> t, t a -> s
mapWithVec :: VecEach s t a b => (forall n. InlineInduction n => Vec n a -> Vec n b) -> s -> t
traverseWithVec :: (VecEach s t a b, Applicative f) => (forall n. InlineInduction n => Vec n a -> f (Vec n b)) -> s -> f t
