{-| This module provides context connector records. A context connector record is a record of connectors (consumers or producers) which depend on some data, called the context. -} module Data.Record.Signal.Context ( -- * Context connector records ContextConsumerRecord, ContextProducerRecord, ContextConnectorRecord, ContextConnectorStyle, consume, produce ) where -- Control import Control.Arrow.Operations as ArrowOperations import Control.Arrow.Transformer.Reader as ReaderArrow -- Data import Data.Record as Record import Data.Record.Context as ContextRecord import Data.Record.Signal as SignalRecord hiding (consume, produce) import qualified Data.Record.Signal as SignalRecord -- FRP.Grapefruit import FRP.Grapefruit.Circuit as Circuit import FRP.Grapefruit.Signal as Signal hiding (consume, produce) -- |Records which contain functions from contexts to consumers as values. type ContextConsumerRecord context record = ContextConnectorRecord context Consumer record -- |Records which contain functions from contexts to producers as values. type ContextProducerRecord context record = ContextConnectorRecord context Producer record {-| Records which contain functions from contexts to connectors (consumers or producers) as values. -} type ContextConnectorRecord context connector record = record (ContextConnectorStyle context connector) type ContextConnectorStyle context connector = ContextStyle context (ConnectorStyle connector) {-| Converts a record of context consumers into a reader arrow which consumes a corresponding record of signals. The concrete context has to be provided as the environment of the reader arrow. -} consume :: (Record SignalKind record) => ContextConsumerRecord context record -> ReaderArrow context (Circuit era) (SignalRecord era record) () consume = connect SignalRecord.consume {-| Converts a record of context producers into a reader arrow which produces a corresponding record of signals. The concrete context has to be provided as the environment of the reader arrow. -} produce :: (Record SignalKind record) => ContextProducerRecord context record -> ReaderArrow context (Circuit era) () (SignalRecord era record) produce = connect SignalRecord.produce connect :: (Record SignalKind record) => (ConnectorRecord connector record -> Circuit era i o) -> ContextConnectorRecord context connector record -> ReaderArrow context (Circuit era) i o connect signalRecordConnect contextConnectorRecord = arrow' where arrow' = proc i -> do context <- readState -< () liftReader $ signalRecordConnect (contextConnectorRecord `app` context) -<< i