{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE ScopedTypeVariables #-}

module DSV.Vector
  ( Vector
  , vectorIndexInt, vectorIndexNat, vectorIndexInteger, nthVectorElement
  , vectorLookup
  , vectorZip, vectorZipWith
  , listToVector, vectorToList
  , emptyVector
  ) where

import DSV.Numbers
import DSV.Prelude

-- base
import Control.Monad ((>=>))

-- vector
import qualified Data.Vector as Vector

type Vector = Vector.Vector

vectorIndexInt :: forall a . Vector a -> Int -> Maybe a
vectorIndexInt :: Vector a -> Int -> Maybe a
vectorIndexInt = Vector a -> Int -> Maybe a
forall a. Vector a -> Int -> Maybe a
(Vector.!?)

vectorIndexNat :: forall a. Vector a -> Natural -> Maybe a
vectorIndexNat :: Vector a -> Natural -> Maybe a
vectorIndexNat Vector a
xs Natural
n = Vector a -> Int -> Maybe a
forall a. Vector a -> Int -> Maybe a
vectorIndexInt Vector a
xs (Natural -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Natural
n)

vectorIndexInteger ::
    forall a .
    Vector a -> Integer -> Maybe a

vectorIndexInteger :: Vector a -> Integer -> Maybe a
vectorIndexInteger Vector a
xs =
    Integer -> Maybe Int
forall n. (Bounded n, Integral n) => Integer -> Maybe n
fromIntegerMaybe (Integer -> Maybe Int) -> (Int -> Maybe a) -> Integer -> Maybe a
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> Vector a -> Int -> Maybe a
forall a. Vector a -> Int -> Maybe a
vectorIndexInt Vector a
xs

vectorZip ::
    forall a b .
    Vector a -> Vector b -> Vector (a, b)

vectorZip :: Vector a -> Vector b -> Vector (a, b)
vectorZip = Vector a -> Vector b -> Vector (a, b)
forall a b. Vector a -> Vector b -> Vector (a, b)
Vector.zip

vectorZipWith ::
    forall a b c  .
    (a -> b -> c) -> Vector a -> Vector b -> Vector c

vectorZipWith :: (a -> b -> c) -> Vector a -> Vector b -> Vector c
vectorZipWith = (a -> b -> c) -> Vector a -> Vector b -> Vector c
forall a b c. (a -> b -> c) -> Vector a -> Vector b -> Vector c
Vector.zipWith

{- |

=== Examples

  * @nthVectorElement 0 ["a", "b", "c"] = Nothing@
  * @nthVectorElement 1 ["a", "b", "c"] = Just "a"@
  * @nthVectorElement 2 ["a", "b", "c"] = Just "b"@
  * @nthVectorElement 3 ["a", "b", "c"] = Just "c"@
  * @nthVectorElement 4 ["a", "b", "c"] = Nothing@

-}

nthVectorElement :: forall a . Integer -> Vector a -> Maybe a
nthVectorElement :: Integer -> Vector a -> Maybe a
nthVectorElement Integer
n Vector a
xs = Vector a -> Integer -> Maybe a
forall a. Vector a -> Integer -> Maybe a
vectorIndexInteger Vector a
xs (Integer
n Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Integer
1)

vectorLookup ::
    forall name value .
    (name -> Bool)
    -> Vector (name, value)
    -> Maybe value

vectorLookup :: (name -> Bool) -> Vector (name, value) -> Maybe value
vectorLookup name -> Bool
f Vector (name, value)
xs =
  case ((name, value) -> Bool) -> [(name, value)] -> [(name, value)]
forall a. (a -> Bool) -> [a] -> [a]
filter (\(name
n, value
_) -> name -> Bool
f name
n) (Vector (name, value) -> [(name, value)]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList Vector (name, value)
xs) of
    [(name
_, value
v)] -> value -> Maybe value
forall a. a -> Maybe a
Just value
v
    [(name, value)]
_ -> Maybe value
forall a. Maybe a
Nothing

listToVector :: forall a . [a] -> Vector a
listToVector :: [a] -> Vector a
listToVector = [a] -> Vector a
forall a. [a] -> Vector a
Vector.fromList

vectorToList :: forall a . Vector a -> [a]
vectorToList :: Vector a -> [a]
vectorToList = Vector a -> [a]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList

emptyVector :: forall a . Vector a
emptyVector :: Vector a
emptyVector = Vector a
forall a. Vector a
Vector.empty