module Bench.Vector.Algo.FindIndexR (findIndexR, findIndexR_naive, findIndexR_manual)
where

import Data.Vector.Unboxed (Vector)
import qualified Data.Vector.Generic as V

findIndexR :: (Double -> Bool, Vector Double) -> Maybe Int
{-# NOINLINE findIndexR #-}
findIndexR :: (Double -> Bool, Vector Double) -> Maybe Int
findIndexR = ((Double -> Bool) -> Vector Double -> Maybe Int)
-> (Double -> Bool, Vector Double) -> Maybe Int
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry (Double -> Bool) -> Vector Double -> Maybe Int
forall (v :: * -> *) a.
Vector v a =>
(a -> Bool) -> v a -> Maybe Int
V.findIndexR

findIndexR_naive :: (Double -> Bool, Vector Double) -> Maybe Int
{-# NOINLINE findIndexR_naive #-}
findIndexR_naive :: (Double -> Bool, Vector Double) -> Maybe Int
findIndexR_naive (Double -> Bool
pred, Vector Double
v) = (Int -> Int) -> Maybe Int -> Maybe Int
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Vector Double -> Int
forall (v :: * -> *) a. Vector v a => v a -> Int
V.length Vector Double
v Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1 Int -> Int -> Int
forall a. Num a => a -> a -> a
-)
    (Maybe Int -> Maybe Int) -> Maybe Int -> Maybe Int
forall a b. (a -> b) -> a -> b
$ (Maybe Int -> Double -> Maybe Int)
-> Maybe Int -> Vector Double -> Maybe Int
forall (v :: * -> *) b a.
Vector v b =>
(a -> b -> a) -> a -> v b -> a
V.foldl (\Maybe Int
a Double
x -> if Double -> Bool
pred Double
x
                        then Int -> Maybe Int
forall a. a -> Maybe a
Just Int
1
                        else Int -> Int
forall a. Enum a => a -> a
succ(Int -> Int) -> Maybe Int -> Maybe Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>Maybe Int
a) Maybe Int
forall a. Maybe a
Nothing Vector Double
v

findIndexR_manual :: (Double -> Bool, Vector Double) -> Maybe Int
{-# NOINLINE findIndexR_manual #-}
findIndexR_manual :: (Double -> Bool, Vector Double) -> Maybe Int
findIndexR_manual (Double -> Bool
pred, Vector Double
v) = Int -> Maybe Int
go (Int -> Maybe Int) -> Int -> Maybe Int
forall a b. (a -> b) -> a -> b
$ Vector Double -> Int
forall (v :: * -> *) a. Vector v a => v a -> Int
V.length Vector Double
v Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1
 where go :: Int -> Maybe Int
go Int
i | Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0                     = Maybe Int
forall a. Maybe a
Nothing
            | Double -> Bool
pred (Vector Double -> Int -> Double
forall (v :: * -> *) a. Vector v a => v a -> Int -> a
V.unsafeIndex Vector Double
v Int
i)  = Int -> Maybe Int
forall a. a -> Maybe a
Just Int
i
            | Bool
otherwise                 = Int -> Maybe Int
go (Int -> Maybe Int) -> Int -> Maybe Int
forall a b. (a -> b) -> a -> b
$ Int
iInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1