{-# LANGUAGE MagicHash #-} module Data.RangeMin.Common.Types (SliceMin, runSliceMin, toSliceMin, LEq, RM, MinIx, runMinIx, pickMinIx, toMinIx, minIxOn, toRM, runRM, onRM, module Data.RangeMin.Common.Types.IPVector{-, ReIx, reIx, minReIx, toReIx-}) where import GHC.Exts import Data.RangeMin.Common.Types.IPVector on :: (b -> b -> c) -> (a -> b) -> a -> a -> c (f `on` g) x y = f (g x) (g y) type RM = (Int# -> Int# -> Int#) newtype MinIx = MinIx {execMinIx :: Int# -> Int# -> Bool} newtype SliceMin = SliceMin {execSliceMin :: Int# -> MinIx} -- newtype ReIx = ReIx {execReIx :: Int# -> Int#} -- | A function of type @'LEq' a@ is used as if it were @('<=')@ for comparison purposes. type LEq a = a -> a -> Bool -- reIx :: ReIx -> Int -> Int -- reIx f (I# i#) = I# (execReIx f i#) -- -- minReIx :: ReIx -> MinIx -> MinIx -- minReIx rIx mIx = mIx `minIxOn` reIx rIx -- -- {-# INLINE toReIx #-} -- toReIx :: (Int -> Int) -> ReIx -- toReIx f = ReIx $ \ i# -> case f (I# i#) of -- I# j# -> j# runSliceMin :: SliceMin -> Int -> MinIx runSliceMin s (I# i#) = execSliceMin s i# {-# INLINE toSliceMin #-} toSliceMin :: (Int -> MinIx) -> SliceMin toSliceMin f = SliceMin $ \ i# -> f (I# i#) {-# INLINE runMinIx #-} runMinIx :: MinIx -> Int -> Int -> Bool runMinIx m (I# i#) (I# j#) = execMinIx m i# j# {-# INLINE minIxOn #-} minIxOn :: MinIx -> (Int -> Int) -> MinIx minIxOn mIx f = toMinIx (runMinIx mIx `on` f) {-# INLINE pickMinIx #-} pickMinIx :: MinIx -> Int -> Int -> Int pickMinIx m i@(I# i#) j@(I# j#) = if execMinIx m i# j# then i else j {-# INLINE toMinIx #-} toMinIx :: (Int -> Int -> Bool) -> MinIx toMinIx f = MinIx $ \ i# j# -> f (I# i#) (I# j#) {-# INLINE toRM #-} toRM :: (Int -> Int -> Int) -> RM toRM f = \ i# j# -> case f (I# i#) (I# j#) of I# k# -> k# runRM :: RM -> Int -> Int -> Int runRM f (I# i#) (I# j#) = I# (f i# j#) {-# INLINE onRM #-} onRM :: (Int -> Int) -> RM -> RM onRM f rm = toRM (\ i j -> f (runRM rm i j))