module VectorExtras.Generic
  ( module Basics,
    fromFoldable,
    fromFoldableNarrowing,
  )
where

import Data.Vector.Generic hiding (foldl')
import qualified VectorExtras.Accumulator as VAcc
import VectorExtras.Basics.Generic as Basics
import VectorExtras.Prelude

{-# INLINE fromFoldable #-}
fromFoldable :: (Foldable f, Vector v a) => f a -> v a
fromFoldable :: forall (f :: * -> *) (v :: * -> *) a.
(Foldable f, Vector v a) =>
f a -> v a
fromFoldable =
  forall (v :: * -> *) a. Vector v a => Accumulator a -> v a
VAcc.toVector forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' (forall a b c. (a -> b -> c) -> b -> a -> c
flip forall a. a -> Accumulator a -> Accumulator a
VAcc.add) forall a. Accumulator a
VAcc.init

{-# INLINE fromFoldableNarrowing #-}
fromFoldableNarrowing :: (Foldable f, Vector v b) => (a -> Maybe b) -> f a -> v b
fromFoldableNarrowing :: forall (f :: * -> *) (v :: * -> *) b a.
(Foldable f, Vector v b) =>
(a -> Maybe b) -> f a -> v b
fromFoldableNarrowing a -> Maybe b
narrow =
  forall (v :: * -> *) a. Vector v a => Accumulator a -> v a
VAcc.toVector forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' Accumulator b -> a -> Accumulator b
step forall a. Accumulator a
VAcc.init
  where
    step :: Accumulator b -> a -> Accumulator b
step Accumulator b
acc a
el = case a -> Maybe b
narrow a
el of
      Maybe b
Nothing -> Accumulator b
acc
      Just b
narrowed -> forall a. a -> Accumulator a -> Accumulator a
VAcc.add b
narrowed Accumulator b
acc