{-# LANGUAGE RecordWildCards #-} {-| Module : Dataflow Description : Timely Dataflow for Haskell Copyright : (c) Double Crown Gaming Co. 2020 License : BSD3 Maintainer : jesse.kempf@doublecrown.co Stability : experimental Timely Dataflow in pure Haskell. -} module Dataflow ( Dataflow, Edge, Timestamp, StateRef, send, readState, writeState, modifyState, statefulVertex, statelessVertex, outputTVar, trace, discard, Program, compile, execute ) where import Control.Monad (void) import Control.Monad.IO.Class (MonadIO (..)) import Control.Monad.State.Strict (evalStateT, execStateT, runStateT) import Data.Traversable (Traversable) import Dataflow.Primitives import Dataflow.Vertices -- | A 'Program' represents a fully-preprocessed 'Dataflow' that may be -- executed against inputs. -- -- @since 0.1.0.0 data Program i = Program { programInput :: Edge i, programState :: DataflowState } -- | Take a 'Dataflow' which takes 'i's as input and compile it into a 'Program'. -- -- @since 0.1.0.0 compile :: MonadIO io => Dataflow (Edge i) -> io (Program i) compile (Dataflow actions) = liftIO $ uncurry Program <$> runStateT actions initDataflowState -- | Feed a traversable collection of inputs to a 'Program'. All inputs provided will -- have the same 'Timestamp' associated with them. -- -- @since 0.1.0.0 execute :: (MonadIO io, Traversable t) => t i -> Program i -> io (Program i) execute corpus Program{..} = liftIO $ do newProgramState <- evalStateT (runDataflow duplicateDataflowState) programState void $ execStateT (runDataflow $ input corpus programInput) newProgramState return $ Program programInput newProgramState