module DeferredFolds.Defs.UnfoldlM where

import qualified Data.ByteString.Internal as ByteString
import qualified Data.ByteString.Short.Internal as ShortByteString
import DeferredFolds.Prelude hiding (foldM, mapM_)
import qualified DeferredFolds.Prelude as A
import DeferredFolds.Types

deriving instance Functor m => Functor (UnfoldlM m)

instance Monad m => Applicative (UnfoldlM m) where
  pure :: a -> UnfoldlM m a
pure a
x =
    (forall x. (x -> a -> m x) -> x -> m x) -> UnfoldlM m a
forall (m :: * -> *) a.
(forall x. (x -> a -> m x) -> x -> m x) -> UnfoldlM m a
UnfoldlM (\x -> a -> m x
step x
init -> x -> a -> m x
step x
init a
x)
  <*> :: UnfoldlM m (a -> b) -> UnfoldlM m a -> UnfoldlM m b
(<*>) = UnfoldlM m (a -> b) -> UnfoldlM m a -> UnfoldlM m b
forall (m :: * -> *) a b. Monad m => m (a -> b) -> m a -> m b
ap

instance Monad m => Alternative (UnfoldlM m) where
  empty :: UnfoldlM m a
empty =
    (forall x. (x -> a -> m x) -> x -> m x) -> UnfoldlM m a
forall (m :: * -> *) a.
(forall x. (x -> a -> m x) -> x -> m x) -> UnfoldlM m a
UnfoldlM ((x -> m x) -> (x -> a -> m x) -> x -> m x
forall a b. a -> b -> a
const x -> m x
forall (m :: * -> *) a. Monad m => a -> m a
return)
  {-# INLINE (<|>) #-}
  <|> :: UnfoldlM m a -> UnfoldlM m a -> UnfoldlM m a
(<|>) (UnfoldlM forall x. (x -> a -> m x) -> x -> m x
left) (UnfoldlM forall x. (x -> a -> m x) -> x -> m x
right) =
    (forall x. (x -> a -> m x) -> x -> m x) -> UnfoldlM m a
forall (m :: * -> *) a.
(forall x. (x -> a -> m x) -> x -> m x) -> UnfoldlM m a
UnfoldlM (\x -> a -> m x
step x
init -> (x -> a -> m x) -> x -> m x
forall x. (x -> a -> m x) -> x -> m x
left x -> a -> m x
step x
init m x -> (x -> m x) -> m x
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (x -> a -> m x) -> x -> m x
forall x. (x -> a -> m x) -> x -> m x
right x -> a -> m x
step)

instance Monad m => Monad (UnfoldlM m) where
  return :: a -> UnfoldlM m a
return = a -> UnfoldlM m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure
  {-# INLINE (>>=) #-}
  >>= :: UnfoldlM m a -> (a -> UnfoldlM m b) -> UnfoldlM m b
(>>=) (UnfoldlM forall x. (x -> a -> m x) -> x -> m x
left) a -> UnfoldlM m b
rightK =
    (forall x. (x -> b -> m x) -> x -> m x) -> UnfoldlM m b
forall (m :: * -> *) a.
(forall x. (x -> a -> m x) -> x -> m x) -> UnfoldlM m a
UnfoldlM ((forall x. (x -> b -> m x) -> x -> m x) -> UnfoldlM m b)
-> (forall x. (x -> b -> m x) -> x -> m x) -> UnfoldlM m b
forall a b. (a -> b) -> a -> b
$ \x -> b -> m x
step x
init ->
      let newStep :: x -> a -> m x
newStep x
output a
x =
            case a -> UnfoldlM m b
rightK a
x of
              UnfoldlM forall x. (x -> b -> m x) -> x -> m x
right ->
                (x -> b -> m x) -> x -> m x
forall x. (x -> b -> m x) -> x -> m x
right x -> b -> m x
step x
output
       in (x -> a -> m x) -> x -> m x
forall x. (x -> a -> m x) -> x -> m x
left x -> a -> m x
newStep x
init

instance Monad m => MonadPlus (UnfoldlM m) where
  mzero :: UnfoldlM m a
mzero = UnfoldlM m a
forall (f :: * -> *) a. Alternative f => f a
empty
  mplus :: UnfoldlM m a -> UnfoldlM m a -> UnfoldlM m a
mplus = UnfoldlM m a -> UnfoldlM m a -> UnfoldlM m a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
(<|>)

instance MonadTrans UnfoldlM where
  lift :: m a -> UnfoldlM m a
lift m a
m = (forall x. (x -> a -> m x) -> x -> m x) -> UnfoldlM m a
forall (m :: * -> *) a.
(forall x. (x -> a -> m x) -> x -> m x) -> UnfoldlM m a
UnfoldlM (\x -> a -> m x
step x
init -> m a
m m a -> (a -> m x) -> m x
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= x -> a -> m x
step x
init)

instance Monad m => Semigroup (UnfoldlM m a) where
  <> :: UnfoldlM m a -> UnfoldlM m a -> UnfoldlM m a
(<>) = UnfoldlM m a -> UnfoldlM m a -> UnfoldlM m a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
(<|>)

instance Monad m => Monoid (UnfoldlM m a) where
  mempty :: UnfoldlM m a
mempty = UnfoldlM m a
forall (f :: * -> *) a. Alternative f => f a
empty
  mappend :: UnfoldlM m a -> UnfoldlM m a -> UnfoldlM m a
mappend = UnfoldlM m a -> UnfoldlM m a -> UnfoldlM m a
forall a. Semigroup a => a -> a -> a
(<>)

instance Foldable (UnfoldlM Identity) where
  {-# INLINE foldMap #-}
  foldMap :: (a -> m) -> UnfoldlM Identity a -> m
foldMap a -> m
inputMonoid = (m -> a -> m) -> m -> UnfoldlM Identity a -> m
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' m -> a -> m
step m
forall a. Monoid a => a
mempty
    where
      step :: m -> a -> m
step m
monoid a
input = m -> m -> m
forall a. Monoid a => a -> a -> a
mappend m
monoid (a -> m
inputMonoid a
input)
  foldl :: (b -> a -> b) -> b -> UnfoldlM Identity a -> b
foldl = (b -> a -> b) -> b -> UnfoldlM Identity a -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl'
  {-# INLINE foldl' #-}
  foldl' :: (b -> a -> b) -> b -> UnfoldlM Identity a -> b
foldl' b -> a -> b
step b
init (UnfoldlM forall x. (x -> a -> Identity x) -> x -> Identity x
run) =
    Identity b -> b
forall a. Identity a -> a
runIdentity ((b -> a -> Identity b) -> b -> Identity b
forall x. (x -> a -> Identity x) -> x -> Identity x
run b -> a -> Identity b
identityStep b
init)
    where
      identityStep :: b -> a -> Identity b
identityStep b
state a
input = b -> Identity b
forall (m :: * -> *) a. Monad m => a -> m a
return (b -> a -> b
step b
state a
input)

instance Eq a => Eq (UnfoldlM Identity a) where
  == :: UnfoldlM Identity a -> UnfoldlM Identity a -> Bool
(==) UnfoldlM Identity a
left UnfoldlM Identity a
right = UnfoldlM Identity a -> [Item (UnfoldlM Identity a)]
forall l. IsList l => l -> [Item l]
toList UnfoldlM Identity a
left [a] -> [a] -> Bool
forall a. Eq a => a -> a -> Bool
== UnfoldlM Identity a -> [Item (UnfoldlM Identity a)]
forall l. IsList l => l -> [Item l]
toList UnfoldlM Identity a
right

instance Show a => Show (UnfoldlM Identity a) where
  show :: UnfoldlM Identity a -> String
show = [a] -> String
forall a. Show a => a -> String
show ([a] -> String)
-> (UnfoldlM Identity a -> [a]) -> UnfoldlM Identity a -> String
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. UnfoldlM Identity a -> [a]
forall l. IsList l => l -> [Item l]
toList

instance IsList (UnfoldlM Identity a) where
  type Item (UnfoldlM Identity a) = a
  fromList :: [Item (UnfoldlM Identity a)] -> UnfoldlM Identity a
fromList [Item (UnfoldlM Identity a)]
list = [a] -> UnfoldlM Identity a
forall (m :: * -> *) (foldable :: * -> *) a.
(Monad m, Foldable foldable) =>
foldable a -> UnfoldlM m a
foldable [a]
[Item (UnfoldlM Identity a)]
list
  toList :: UnfoldlM Identity a -> [Item (UnfoldlM Identity a)]
toList = (a -> [a] -> [a]) -> [a] -> UnfoldlM Identity a -> [a]
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (:) []

-- | Check whether it's empty
{-# INLINE null #-}
null :: Monad m => UnfoldlM m input -> m Bool
null :: UnfoldlM m input -> m Bool
null (UnfoldlM forall x. (x -> input -> m x) -> x -> m x
run) = (Bool -> input -> m Bool) -> Bool -> m Bool
forall x. (x -> input -> m x) -> x -> m x
run (\Bool
_ input
_ -> Bool -> m Bool
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False) Bool
True

-- | Perform a monadic strict left fold
{-# INLINE foldlM' #-}
foldlM' :: Monad m => (output -> input -> m output) -> output -> UnfoldlM m input -> m output
foldlM' :: (output -> input -> m output)
-> output -> UnfoldlM m input -> m output
foldlM' output -> input -> m output
step output
init (UnfoldlM forall x. (x -> input -> m x) -> x -> m x
run) =
  (output -> input -> m output) -> output -> m output
forall x. (x -> input -> m x) -> x -> m x
run output -> input -> m output
step output
init

-- | A more efficient implementation of mapM_
{-# INLINE mapM_ #-}
mapM_ :: Monad m => (input -> m ()) -> UnfoldlM m input -> m ()
mapM_ :: (input -> m ()) -> UnfoldlM m input -> m ()
mapM_ input -> m ()
step = (() -> input -> m ()) -> () -> UnfoldlM m input -> m ()
forall (m :: * -> *) output input.
Monad m =>
(output -> input -> m output)
-> output -> UnfoldlM m input -> m output
foldlM' ((input -> m ()) -> () -> input -> m ()
forall a b. a -> b -> a
const input -> m ()
step) ()

-- | Same as 'mapM_' with arguments flipped
{-# INLINE forM_ #-}
forM_ :: Monad m => UnfoldlM m input -> (input -> m ()) -> m ()
forM_ :: UnfoldlM m input -> (input -> m ()) -> m ()
forM_ = ((input -> m ()) -> UnfoldlM m input -> m ())
-> UnfoldlM m input -> (input -> m ()) -> m ()
forall a b c. (a -> b -> c) -> b -> a -> c
flip (input -> m ()) -> UnfoldlM m input -> m ()
forall (m :: * -> *) input.
Monad m =>
(input -> m ()) -> UnfoldlM m input -> m ()
mapM_

-- | Apply a Gonzalez fold
{-# INLINE fold #-}
fold :: Fold input output -> UnfoldlM Identity input -> output
fold :: Fold input output -> UnfoldlM Identity input -> output
fold (Fold x -> input -> x
step x
init x -> output
extract) = x -> output
extract (x -> output)
-> (UnfoldlM Identity input -> x)
-> UnfoldlM Identity input
-> output
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. (x -> input -> x) -> x -> UnfoldlM Identity input -> x
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' x -> input -> x
step x
init

-- | Apply a monadic Gonzalez fold
{-# INLINE foldM #-}
foldM :: Monad m => FoldM m input output -> UnfoldlM m input -> m output
foldM :: FoldM m input output -> UnfoldlM m input -> m output
foldM (FoldM x -> input -> m x
step m x
init x -> m output
extract) UnfoldlM m input
view =
  do
    x
initialState <- m x
init
    x
finalState <- (x -> input -> m x) -> x -> UnfoldlM m input -> m x
forall (m :: * -> *) output input.
Monad m =>
(output -> input -> m output)
-> output -> UnfoldlM m input -> m output
foldlM' x -> input -> m x
step x
initialState UnfoldlM m input
view
    x -> m output
extract x
finalState

-- | Lift a fold input mapping function into a mapping of unfolds
{-# INLINE mapFoldMInput #-}
mapFoldMInput :: Monad m => (forall x. FoldM m b x -> FoldM m a x) -> UnfoldlM m a -> UnfoldlM m b
mapFoldMInput :: (forall x. FoldM m b x -> FoldM m a x)
-> UnfoldlM m a -> UnfoldlM m b
mapFoldMInput forall x. FoldM m b x -> FoldM m a x
newFoldM UnfoldlM m a
unfoldM = (forall x. (x -> b -> m x) -> x -> m x) -> UnfoldlM m b
forall (m :: * -> *) a.
(forall x. (x -> a -> m x) -> x -> m x) -> UnfoldlM m a
UnfoldlM ((forall x. (x -> b -> m x) -> x -> m x) -> UnfoldlM m b)
-> (forall x. (x -> b -> m x) -> x -> m x) -> UnfoldlM m b
forall a b. (a -> b) -> a -> b
$ \x -> b -> m x
step x
init -> FoldM m a x -> UnfoldlM m a -> m x
forall (m :: * -> *) input output.
Monad m =>
FoldM m input output -> UnfoldlM m input -> m output
foldM (FoldM m b x -> FoldM m a x
forall x. FoldM m b x -> FoldM m a x
newFoldM ((x -> b -> m x) -> m x -> (x -> m x) -> FoldM m b x
forall (m :: * -> *) a b x.
(x -> a -> m x) -> m x -> (x -> m b) -> FoldM m a b
FoldM x -> b -> m x
step (x -> m x
forall (m :: * -> *) a. Monad m => a -> m a
return x
init) x -> m x
forall (m :: * -> *) a. Monad m => a -> m a
return)) UnfoldlM m a
unfoldM

-- | Construct from any foldable
{-# INLINE foldable #-}
foldable :: (Monad m, Foldable foldable) => foldable a -> UnfoldlM m a
foldable :: foldable a -> UnfoldlM m a
foldable foldable a
foldable = (forall x. (x -> a -> m x) -> x -> m x) -> UnfoldlM m a
forall (m :: * -> *) a.
(forall x. (x -> a -> m x) -> x -> m x) -> UnfoldlM m a
UnfoldlM (\x -> a -> m x
step x
init -> (x -> a -> m x) -> x -> foldable a -> m x
forall (t :: * -> *) (m :: * -> *) b a.
(Foldable t, Monad m) =>
(b -> a -> m b) -> b -> t a -> m b
A.foldlM x -> a -> m x
step x
init foldable a
foldable)

-- | Construct from a specification of how to execute a left-fold
{-# INLINE foldlRunner #-}
foldlRunner :: Monad m => (forall x. (x -> a -> x) -> x -> x) -> UnfoldlM m a
foldlRunner :: (forall x. (x -> a -> x) -> x -> x) -> UnfoldlM m a
foldlRunner forall x. (x -> a -> x) -> x -> x
run = (forall x. (x -> a -> m x) -> x -> m x) -> UnfoldlM m a
forall (m :: * -> *) a.
(forall x. (x -> a -> m x) -> x -> m x) -> UnfoldlM m a
UnfoldlM (\x -> a -> m x
stepM x
state -> (m x -> a -> m x) -> m x -> m x
forall x. (x -> a -> x) -> x -> x
run (\m x
stateM a
a -> m x
stateM m x -> (x -> m x) -> m x
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \x
state -> x -> a -> m x
stepM x
state a
a) (x -> m x
forall (m :: * -> *) a. Monad m => a -> m a
return x
state))

-- | Construct from a specification of how to execute a right-fold
{-# INLINE foldrRunner #-}
foldrRunner :: Monad m => (forall x. (a -> x -> x) -> x -> x) -> UnfoldlM m a
foldrRunner :: (forall x. (a -> x -> x) -> x -> x) -> UnfoldlM m a
foldrRunner forall x. (a -> x -> x) -> x -> x
run = (forall x. (x -> a -> m x) -> x -> m x) -> UnfoldlM m a
forall (m :: * -> *) a.
(forall x. (x -> a -> m x) -> x -> m x) -> UnfoldlM m a
UnfoldlM (\x -> a -> m x
stepM -> (a -> (x -> m x) -> x -> m x) -> (x -> m x) -> x -> m x
forall x. (a -> x -> x) -> x -> x
run (\a
x x -> m x
k x
z -> x -> a -> m x
stepM x
z a
x m x -> (x -> m x) -> m x
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= x -> m x
k) x -> m x
forall (m :: * -> *) a. Monad m => a -> m a
return)

unfoldr :: Monad m => Unfoldr a -> UnfoldlM m a
unfoldr :: Unfoldr a -> UnfoldlM m a
unfoldr (Unfoldr forall x. (a -> x -> x) -> x -> x
unfoldr) = (forall x. (a -> x -> x) -> x -> x) -> UnfoldlM m a
forall (m :: * -> *) a.
Monad m =>
(forall x. (a -> x -> x) -> x -> x) -> UnfoldlM m a
foldrRunner forall x. (a -> x -> x) -> x -> x
unfoldr

-- | Filter the values given a predicate
{-# INLINE filter #-}
filter :: Monad m => (a -> m Bool) -> UnfoldlM m a -> UnfoldlM m a
filter :: (a -> m Bool) -> UnfoldlM m a -> UnfoldlM m a
filter a -> m Bool
test (UnfoldlM forall x. (x -> a -> m x) -> x -> m x
run) = (forall x. (x -> a -> m x) -> x -> m x) -> UnfoldlM m a
forall (m :: * -> *) a.
(forall x. (x -> a -> m x) -> x -> m x) -> UnfoldlM m a
UnfoldlM (\x -> a -> m x
step -> (x -> a -> m x) -> x -> m x
forall x. (x -> a -> m x) -> x -> m x
run (\x
state a
element -> a -> m Bool
test a
element m Bool -> (Bool -> m x) -> m x
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= m x -> m x -> Bool -> m x
forall a. a -> a -> Bool -> a
bool (x -> m x
forall (m :: * -> *) a. Monad m => a -> m a
return x
state) (x -> a -> m x
step x
state a
element)))

-- | Ints in the specified inclusive range
{-# INLINE intsInRange #-}
intsInRange :: Monad m => Int -> Int -> UnfoldlM m Int
intsInRange :: Int -> Int -> UnfoldlM m Int
intsInRange Int
from Int
to =
  (forall x. (x -> Int -> m x) -> x -> m x) -> UnfoldlM m Int
forall (m :: * -> *) a.
(forall x. (x -> a -> m x) -> x -> m x) -> UnfoldlM m a
UnfoldlM ((forall x. (x -> Int -> m x) -> x -> m x) -> UnfoldlM m Int)
-> (forall x. (x -> Int -> m x) -> x -> m x) -> UnfoldlM m Int
forall a b. (a -> b) -> a -> b
$ \x -> Int -> m x
step x
init ->
    let loop :: x -> Int -> m x
loop !x
state Int
int =
          if Int
int Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
to
            then do
              x
newState <- x -> Int -> m x
step x
state Int
int
              x -> Int -> m x
loop x
newState (Int -> Int
forall a. Enum a => a -> a
succ Int
int)
            else x -> m x
forall (m :: * -> *) a. Monad m => a -> m a
return x
state
     in x -> Int -> m x
loop x
init Int
from

-- | TVar contents
{-# INLINE tVarValue #-}
tVarValue :: TVar a -> UnfoldlM STM a
tVarValue :: TVar a -> UnfoldlM STM a
tVarValue TVar a
var = (forall x. (x -> a -> STM x) -> x -> STM x) -> UnfoldlM STM a
forall (m :: * -> *) a.
(forall x. (x -> a -> m x) -> x -> m x) -> UnfoldlM m a
UnfoldlM ((forall x. (x -> a -> STM x) -> x -> STM x) -> UnfoldlM STM a)
-> (forall x. (x -> a -> STM x) -> x -> STM x) -> UnfoldlM STM a
forall a b. (a -> b) -> a -> b
$ \x -> a -> STM x
step x
state -> do
  a
a <- TVar a -> STM a
forall a. TVar a -> STM a
readTVar TVar a
var
  x -> a -> STM x
step x
state a
a

-- | Change the base monad using invariant natural transformations
{-# INLINE hoist #-}
hoist :: (forall a. m a -> n a) -> (forall a. n a -> m a) -> UnfoldlM m a -> UnfoldlM n a
hoist :: (forall a. m a -> n a)
-> (forall a. n a -> m a) -> UnfoldlM m a -> UnfoldlM n a
hoist forall a. m a -> n a
trans1 forall a. n a -> m a
trans2 (UnfoldlM forall x. (x -> a -> m x) -> x -> m x
unfold) = (forall x. (x -> a -> n x) -> x -> n x) -> UnfoldlM n a
forall (m :: * -> *) a.
(forall x. (x -> a -> m x) -> x -> m x) -> UnfoldlM m a
UnfoldlM ((forall x. (x -> a -> n x) -> x -> n x) -> UnfoldlM n a)
-> (forall x. (x -> a -> n x) -> x -> n x) -> UnfoldlM n a
forall a b. (a -> b) -> a -> b
$ \x -> a -> n x
step x
init ->
  m x -> n x
forall a. m a -> n a
trans1 ((x -> a -> m x) -> x -> m x
forall x. (x -> a -> m x) -> x -> m x
unfold (\x
a a
b -> n x -> m x
forall a. n a -> m a
trans2 (x -> a -> n x
step x
a a
b)) x
init)

-- | Bytes of a bytestring
{-# INLINEABLE byteStringBytes #-}
byteStringBytes :: ByteString -> UnfoldlM IO Word8
byteStringBytes :: ByteString -> UnfoldlM IO Word8
byteStringBytes (ByteString.PS ForeignPtr Word8
fp Int
off Int
len) =
  (forall x. (x -> Word8 -> IO x) -> x -> IO x) -> UnfoldlM IO Word8
forall (m :: * -> *) a.
(forall x. (x -> a -> m x) -> x -> m x) -> UnfoldlM m a
UnfoldlM ((forall x. (x -> Word8 -> IO x) -> x -> IO x)
 -> UnfoldlM IO Word8)
-> (forall x. (x -> Word8 -> IO x) -> x -> IO x)
-> UnfoldlM IO Word8
forall a b. (a -> b) -> a -> b
$ \x -> Word8 -> IO x
step x
init ->
    ForeignPtr Word8 -> (Ptr Word8 -> IO x) -> IO x
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr Word8
fp ((Ptr Word8 -> IO x) -> IO x) -> (Ptr Word8 -> IO x) -> IO x
forall a b. (a -> b) -> a -> b
$ \Ptr Word8
ptr ->
      let endPtr :: Ptr Word8
endPtr = Ptr Word8 -> Int -> Ptr Word8
forall a b. Ptr a -> Int -> Ptr b
plusPtr Ptr Word8
ptr (Int
off Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
len)
          iterate :: x -> Ptr Word8 -> IO x
iterate !x
state !Ptr Word8
ptr =
            if Ptr Word8
ptr Ptr Word8 -> Ptr Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Ptr Word8
endPtr
              then x -> IO x
forall (m :: * -> *) a. Monad m => a -> m a
return x
state
              else do
                Word8
x <- Ptr Word8 -> IO Word8
forall a. Storable a => Ptr a -> IO a
peek Ptr Word8
ptr
                x
newState <- x -> Word8 -> IO x
step x
state Word8
x
                x -> Ptr Word8 -> IO x
iterate x
newState (Ptr Word8 -> Int -> Ptr Word8
forall a b. Ptr a -> Int -> Ptr b
plusPtr Ptr Word8
ptr Int
1)
       in x -> Ptr Word8 -> IO x
iterate x
init (Ptr Word8 -> Int -> Ptr Word8
forall a b. Ptr a -> Int -> Ptr b
plusPtr Ptr Word8
ptr Int
off)

-- | Bytes of a short bytestring
{-# INLINE shortByteStringBytes #-}
shortByteStringBytes :: Monad m => ShortByteString -> UnfoldlM m Word8
shortByteStringBytes :: ShortByteString -> UnfoldlM m Word8
shortByteStringBytes (ShortByteString.SBS ByteArray#
ba#) = PrimArray Word8 -> UnfoldlM m Word8
forall (m :: * -> *) prim.
(Monad m, Prim prim) =>
PrimArray prim -> UnfoldlM m prim
primArray (ByteArray# -> PrimArray Word8
forall a. ByteArray# -> PrimArray a
PrimArray ByteArray#
ba#)

-- | Elements of a prim array
{-# INLINE primArray #-}
primArray :: (Monad m, Prim prim) => PrimArray prim -> UnfoldlM m prim
primArray :: PrimArray prim -> UnfoldlM m prim
primArray PrimArray prim
pa = (forall x. (x -> prim -> m x) -> x -> m x) -> UnfoldlM m prim
forall (m :: * -> *) a.
(forall x. (x -> a -> m x) -> x -> m x) -> UnfoldlM m a
UnfoldlM ((forall x. (x -> prim -> m x) -> x -> m x) -> UnfoldlM m prim)
-> (forall x. (x -> prim -> m x) -> x -> m x) -> UnfoldlM m prim
forall a b. (a -> b) -> a -> b
$ \x -> prim -> m x
f x
z -> (x -> prim -> m x) -> x -> PrimArray prim -> m x
forall a (m :: * -> *) b.
(Prim a, Monad m) =>
(b -> a -> m b) -> b -> PrimArray a -> m b
foldlPrimArrayM' x -> prim -> m x
f x
z PrimArray prim
pa

-- | Elements of a prim array coming paired with indices
{-# INLINE primArrayWithIndices #-}
primArrayWithIndices :: (Monad m, Prim prim) => PrimArray prim -> UnfoldlM m (Int, prim)
primArrayWithIndices :: PrimArray prim -> UnfoldlM m (Int, prim)
primArrayWithIndices PrimArray prim
pa = (forall x. (x -> (Int, prim) -> m x) -> x -> m x)
-> UnfoldlM m (Int, prim)
forall (m :: * -> *) a.
(forall x. (x -> a -> m x) -> x -> m x) -> UnfoldlM m a
UnfoldlM ((forall x. (x -> (Int, prim) -> m x) -> x -> m x)
 -> UnfoldlM m (Int, prim))
-> (forall x. (x -> (Int, prim) -> m x) -> x -> m x)
-> UnfoldlM m (Int, prim)
forall a b. (a -> b) -> a -> b
$ \x -> (Int, prim) -> m x
step x
state ->
  let !size :: Int
size = PrimArray prim -> Int
forall a. Prim a => PrimArray a -> Int
sizeofPrimArray PrimArray prim
pa
      iterate :: Int -> x -> m x
iterate Int
index !x
state =
        if Int
index Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
size
          then do
            x
newState <- x -> (Int, prim) -> m x
step x
state (Int
index, PrimArray prim -> Int -> prim
forall a. Prim a => PrimArray a -> Int -> a
indexPrimArray PrimArray prim
pa Int
index)
            Int -> x -> m x
iterate (Int -> Int
forall a. Enum a => a -> a
succ Int
index) x
newState
          else x -> m x
forall (m :: * -> *) a. Monad m => a -> m a
return x
state
   in Int -> x -> m x
iterate Int
0 x
state