module Potoki.Core.Transform.State where import Potoki.Core.Prelude import Potoki.Core.Types import Potoki.Core.Transform.Instances () import qualified Potoki.Core.Fetch as A import qualified Control.Monad.Trans.State.Strict as O import qualified Acquire.Acquire as M {-| Notice that you can control the emission of output of each step by producing a list of outputs and then composing the transform with the "list" transform. -} {-# INLINE runState #-} runState :: (input -> O.State state output) -> state -> Transform input (output, state) runState stateFn initialState = Transform $ \ (A.Fetch fetchIO) -> M.Acquire $ do stateRef <- newIORef initialState return $ (, return ()) $ A.Fetch $ fetchIO >>= \case Just input -> do currentState <- readIORef stateRef case O.runState (stateFn input) currentState of (output, newState) -> do writeIORef stateRef newState return (Just (output, newState)) Nothing -> return Nothing {-# INLINE evalState #-} evalState :: (input -> O.State state output) -> state -> Transform input output evalState stateFn initialState = rmap fst (runState stateFn initialState) {-# INLINE execState #-} execState :: (input -> O.State state output) -> state -> Transform input state execState stateFn initialState = rmap snd (runState stateFn initialState)