module Data.RangeMin.Common.Types (SliceMin, runSliceMin, toSliceMin, LEq, RM, MinIx, runMinIx, pickMinIx, toMinIx, minIxOn, toRM, runRM, onRM) where
import GHC.Exts
import Data.RangeMin.Common.Combinators
newtype RM = RM {execRM :: Int# -> Int# -> Int#}
newtype MinIx = MinIx {execMinIx :: Int# -> Int# -> Bool}
newtype SliceMin = SliceMin {execSliceMin :: Int# -> MinIx}
type LEq a = a -> a -> Bool
runSliceMin :: SliceMin -> Int -> MinIx
runSliceMin s (I# i#) = execSliceMin s i#
toSliceMin :: (Int -> MinIx) -> SliceMin
toSliceMin f = SliceMin $ \ i# -> f (I# i#)
runMinIx :: MinIx -> Int -> Int -> Bool
runMinIx m (I# i#) (I# j#) = execMinIx m i# j#
minIxOn :: MinIx -> (Int -> Int) -> MinIx
minIxOn mIx f = toMinIx (runMinIx mIx `on` f)
pickMinIx :: MinIx -> Int -> Int -> Int
pickMinIx m i@(I# i#) j@(I# j#) = if execMinIx m i# j# then i else j
toMinIx :: (Int -> Int -> Bool) -> MinIx
toMinIx f = MinIx $ \ i# j# -> f (I# i#) (I# j#)
toRM :: (Int -> Int -> Int) -> RM
toRM f = RM $ \ i# j# -> case f (I# i#) (I# j#) of
I# k# -> k#
runRM :: RM -> Int -> Int -> Int
runRM f (I# i#) (I# j#) = I# (execRM f i# j#)
onRM :: (Int -> Int) -> RM -> RM
onRM f rm = toRM (\ i j -> f (runRM rm i j))