    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