module AppPrelude (module ClassyPrelude, module Data.Ord, Vector, (!!), (/), (%), inRange, maybeFilter, findTraverseIndex, untilM, elem, notElem) where

import           ClassyPrelude        hiding (Vector, elem, mask, notElem, (/), (>>), (^))

import           Data.Foldable        (elem, notElem)
import           Data.Int             (Int16)
import           Data.Ord
import           Data.Vector.Storable (Vector)


{-# SPECIALIZE (!!) :: Vector Int16 -> Int -> Int16 #-}
{-# SPECIALIZE (!!) :: Vector Word64 -> Int -> Word64 #-}
{-# INLINE (!!)  #-}
infixl 9 !!
(!!) :: Storable a => Vector a -> Int -> a
!! :: forall a. Storable a => Vector a -> Int -> a
(!!) !Vector a
x !Int
y = Vector a -> Index (Vector a) -> Element (Vector a)
forall seq. IsSequence seq => seq -> Index seq -> Element seq
unsafeIndex Vector a
x Int
Index (Vector a)
y


{-# SPECIALIZE (/) :: Int16 -> Int16 -> Int16 #-}
{-# SPECIALIZE (/) :: Int -> Int -> Int #-}
{-# INLINE (/)  #-}
infixl 7 /
(/) :: Integral a => a -> a -> a
/ :: forall a. Integral a => a -> a -> a
(/) !a
x !a
y = a -> a -> a
forall a. Integral a => a -> a -> a
quot a
x a
y

{-# SPECIALIZE (%) :: Int16 -> Int16 -> Int16 #-}
{-# SPECIALIZE (%) :: Int -> Int -> Int #-}
{-# SPECIALIZE (%) :: Word64 -> Word64 -> Word64 #-}
{-# INLINE (%)  #-}
infixl 7 %
(%) :: Integral a => a -> a -> a
% :: forall a. Integral a => a -> a -> a
(%) !a
x !a
y = a -> a -> a
forall a. Integral a => a -> a -> a
rem a
x a
y


inRange :: Int -> Int -> Int -> Bool
inRange :: Int -> Int -> Int -> Bool
inRange Int
lo Int
hi Int
x = Int
lo Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
x Bool -> Bool -> Bool
&& Int
x Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
hi


{-# INLINE maybeFilter  #-}
maybeFilter :: (a -> Bool) -> Maybe a -> Maybe a
maybeFilter :: forall a. (a -> Bool) -> Maybe a -> Maybe a
maybeFilter !a -> Bool
predicate Maybe a
ma = do
  !a
a <- Maybe a
ma
  if a -> Bool
predicate a
a
    then Maybe a
ma
    else Maybe a
forall a. Maybe a
Nothing


{-# INLINE findTraverseIndex  #-}
findTraverseIndex :: Monad m => (Int -> a -> m (Maybe b)) -> [a] -> m (Maybe b)
findTraverseIndex :: forall (m :: * -> *) a b.
Monad m =>
(Int -> a -> m (Maybe b)) -> [a] -> m (Maybe b)
findTraverseIndex !Int -> a -> m (Maybe b)
f = Int -> [a] -> m (Maybe b)
go Int
0
  where
    go :: Int -> [a] -> m (Maybe b)
go !Int
i (!a
x : [a]
xs) = do
      Maybe b
result <- Int -> a -> m (Maybe b)
f Int
i a
x
      m (Maybe b) -> (b -> m (Maybe b)) -> Maybe b -> m (Maybe b)
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (Int -> [a] -> m (Maybe b)
go (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) [a]
xs) (Maybe b -> m (Maybe b)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Maybe b -> m (Maybe b)) -> (b -> Maybe b) -> b -> m (Maybe b)
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. b -> Maybe b
forall a. a -> Maybe a
Just) Maybe b
result
    go Int
_ [] =
      Maybe b -> m (Maybe b)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe b
forall a. Maybe a
Nothing


{-# INLINE untilM  #-}
untilM :: Monad m => (a -> m Bool) -> [a] -> m ()
untilM :: forall (m :: * -> *) a. Monad m => (a -> m Bool) -> [a] -> m ()
untilM !a -> m Bool
f = [a] -> m ()
go
  where
    go :: [a] -> m ()
go (!a
x : [a]
xs) = m Bool -> m () -> m ()
forall (m :: * -> *). Monad m => m Bool -> m () -> m ()
unlessM (a -> m Bool
f a
x) ([a] -> m ()
go [a]
xs)
    go []        = () -> m ()
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()