grapefruit-records-0.1.0.0: src/Data/Record/Signal/Context.hs
{-|
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