    {-# OPTIONS_GHC -Wno-redundant-constraints -Wno-orphans #-}

    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 :: forall a. 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)
      <*> :: forall a b. 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 :: forall a. 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 a. a -> m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return)
      {-# INLINE (<|>) #-}
      <|> :: forall a. 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 a b. m a -> (a -> m b) -> m b
    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 :: forall a. a -> UnfoldlM m a
    return = a -> UnfoldlM m a
    forall a. a -> UnfoldlM m a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure
      {-# INLINE (>>=) #-}
      >>= :: forall a b. 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 :: forall a. UnfoldlM m a
    mzero = UnfoldlM m a
    forall a. UnfoldlM m a
    forall (f :: * -> *) a. Alternative f => f a
    empty
      mplus :: forall a. UnfoldlM m a -> UnfoldlM m a -> UnfoldlM m a
    mplus = UnfoldlM m a -> UnfoldlM m a -> UnfoldlM m a
    forall a. 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 :: forall (m :: * -> *) a. Monad m => 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 a b. m a -> (a -> m b) -> m b
    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 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 a. 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 :: forall m a. Monoid m => (a -> m) -> UnfoldlM Identity a -> m
    foldMap a -> m
    inputMonoid = (m -> a -> m) -> m -> UnfoldlM Identity a -> m
    forall b a. (b -> a -> b) -> b -> UnfoldlM Identity a -> b
    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 :: forall b a. (b -> a -> b) -> b -> UnfoldlM Identity a -> b
    foldl = (b -> a -> b) -> b -> UnfoldlM Identity a -> b
    forall b a. (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' :: forall b a. (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 a. a -> Identity a
    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 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
    . UnfoldlM Identity a -> [a]
    UnfoldlM Identity a -> [Item (UnfoldlM Identity 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 a b. (a -> b -> b) -> b -> UnfoldlM Identity a -> b
    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 :: forall (m :: * -> *) input. Monad m => 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 a. a -> m a
    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' :: forall (m :: * -> *) output input.
    Monad m =>
    (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_ :: forall (m :: * -> *) input.
    Monad m =>
    (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_ :: forall (m :: * -> *) input.
    Monad m =>
    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 :: forall input output.
    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 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
    . (x -> input -> x) -> x -> UnfoldlM Identity input -> x
    forall b a. (b -> a -> b) -> b -> UnfoldlM Identity a -> b
    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 :: forall (m :: * -> *) input output.
    Monad m =>
    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
        initialState <- m x
    init
        finalState <- foldlM' step initialState view
        extract 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 (m :: * -> *) b a.
    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
    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 a. a -> m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return x
    init) x -> m x
    forall a. a -> m a
    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 :: forall (m :: * -> *) (foldable :: * -> *) a.
    (Monad m, Foldable 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 (m :: * -> *) a.
    Monad m =>
    (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 a b. m a -> (a -> m b) -> m b
    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 a. a -> m a
    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 (m :: * -> *) a.
    Monad m =>
    (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 a b. m a -> (a -> m b) -> m b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= x -> m x
    k) x -> m x
    forall a. a -> m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return)

    unfoldr :: (Monad m) => Unfoldr a -> UnfoldlM m a
    unfoldr :: forall (m :: * -> *) a. Monad m => 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 (a -> x -> x) -> x -> x
    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 :: forall (m :: * -> *) a.
    Monad m =>
    (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 a b. m a -> (a -> m b) -> m b
    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 a. a -> m a
    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 :: forall (m :: * -> *). Monad m => 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
                  newState <- x -> Int -> m x
    step x
    state Int
    int
                  loop newState (succ int)
                else x -> m x
    forall a. a -> m a
    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 :: forall a. 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 <- TVar a -> STM a
    forall a. TVar a -> STM a
    readTVar TVar a
    var
      step state 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 (m :: * -> *) (n :: * -> *) a.
    (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 a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return x
    state
                  else do
                    x <- Ptr Word8 -> IO Word8
    forall a. Storable a => Ptr a -> IO a
    peek Ptr Word8
    ptr
                    newState <- step state x
                    iterate newState (plusPtr ptr 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 :: forall (m :: * -> *).
    Monad m =>
    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 :: forall (m :: * -> *) prim.
    (Monad m, Prim prim) =>
    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 :: forall (m :: * -> *) prim.
    (Monad m, Prim prim) =>
    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
                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)
                iterate (succ index) newState
              else x -> m x
    forall a. a -> m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return x
    state
       in Int -> x -> m x
    iterate Int
    0 x
    state