content: {-# LANGUAGE LambdaCase #-}
  {-# LANGUAGE LinearTypes #-}
  {-# LANGUAGE QualifiedDo #-}
  {-# LANGUAGE RecordWildCards #-}
  {-# OPTIONS_GHC -Wno-name-shadowing #-}
  {-# OPTIONS_HADDOCK hide #-}
  
  -- | This module contains functions for interoperating with other
  -- streaming libraries.
  module Streaming.Linear.Internal.Interop
    ( -- * Interoperating with other streaming libraries
      reread,
    )
  where
  
  import qualified Control.Functor.Linear as Control
  import Data.Unrestricted.Linear
  import Prelude.Linear (($))
  import Streaming.Linear.Internal.Produce
  import Streaming.Linear.Internal.Type
  import Prelude (Maybe (..))
  
  -- | Read an @IORef (Maybe a)@ or a similar device until it reads @Nothing@.
  --    @reread@ provides convenient exit from the @io-streams@ library
  --
  -- > reread readIORef    :: IORef (Maybe a) -> Stream (Of a) IO ()
  -- > reread Streams.read :: System.IO.Streams.InputStream a -> Stream (Of a) IO ()
  reread ::
    (Control.Monad m) =>
    (s -> m (Ur (Maybe a))) ->
    s ->
    Stream (Of a) m ()
  reread f s = reread' f s
    where
      reread' ::
        (Control.Monad m) =>
        (s -> m (Ur (Maybe a))) ->
        s ->
        Stream (Of a) m ()
      reread' f s = Effect $ Control.do
        Ur maybeA <- f s
        case maybeA of
          Nothing -> Control.return $ Return ()
          Just a -> Control.return $ (yield a Control.>> reread f s)
  {-# INLINEABLE reread #-}
  