{-# OPTIONS_GHC -fglasgow-exts #-}------------------------------------------------------------------------------- |-- Module : Control.Arrow.Internals-- Copyright : (c) Ross Paterson 2003-- License : BSD-style (see the LICENSE file in the distribution)---- Maintainer : ross@soi.city.ac.uk-- Stability : experimental-- Portability : non-portable (multi-parameter type classes)---- Manipulation of composite arrow types, beyond the basic lifting and-- encapsulation provided with each arrow transformer.---- The signatures are designed to be compatible with the proposed notation-- for arrows, cf. <http://www.haskell.org/arrows/>.-- #hidemoduleControl.Arrow.Internals(ArrowAddState(..),ArrowAddReader(..),ArrowAddWriter(..),ArrowAddError(..),ArrowAddStream(..),)whereimportControl.ArrowimportControl.Arrow.OperationsimportData.Stream-- | Adding a 'Control.Arrow.Transformer.State.StateArrow' to an-- arrow type, but not necessarily as the outer arrow transformer.---- Typically a composite arrow type is built by applying a series-- of arrow transformer to a base arrow (usually either a function-- arrow or a 'Kleisli' arrow. One can add a transformer to the-- top of this stack using the 'Control.Arrow.Transformer.lift'-- method of the 'Control.Arrow.Transformer.ArrowTransformer' class,-- or remove a state transformer from the top of the stack using the-- 'Control.Arrow.Transformer.State.runState' encapsulation operator.-- The methods of this class add and remove state transformers anywhere-- in the stack. In the instance---- > instance Arrow a => ArrowAddState s (ArrowState s a) a---- they are equivalent to 'Control.Arrow.Transformer.lift' and-- 'Control.Arrow.Transformer.State.runState' respectively.-- Instances are lifted through other transformers with---- > instance ArrowAddState s a a' =>-- > ArrowAddState s (FooArrow a) (FooArrow a')class(ArrowStatesa,Arrowa')=>ArrowAddStatesaa'|a->a'where-- | Lift a computation from an arrow to one with an added state.---- Typical usage in arrow notation:---- > proc p -> ...-- > (|liftState cmd|)liftState::a'eb->aeb-- | Elimination of a state transformer from a computation,-- exposing the initial and final states.---- Typical usage in arrow notation:---- > proc p -> do-- > ...-- > (result, final_state) <- (|elimState cmd|) init_stateelimState::aeb->a'(e,s)(b,s)-- | Adding a 'Control.Arrow.Transformer.Reader.ReaderArrow' to an-- arrow type, but not necessarily as the outer arrow transformer.---- Typically a composite arrow type is built by applying a series-- of arrow transformer to a base arrow (usually either a function-- arrow or a 'Kleisli' arrow. One can add a transformer to the-- top of this stack using the 'Control.Arrow.Transformer.lift'-- method of the 'Control.Arrow.Transformer.ArrowTransformer' class,-- or remove a state transformer from the top of the stack using the-- 'Control.Arrow.Transformer.Reader.runReader' encapsulation operator.-- The methods of this class add and remove state transformers anywhere-- in the stack. In the instance---- > instance Arrow a => ArrowAddReader r (ArrowReader r a) a---- they are equivalent to 'Control.Arrow.Transformer.lift' and-- 'Control.Arrow.Transformer.Reader.runReader' respectively.-- Instances are lifted through other transformers with---- > instance ArrowAddReader r a a' =>-- > ArrowAddReader r (FooArrow a) (FooArrow a')class(ArrowReaderra,Arrowa')=>ArrowAddReaderraa'|a->a'where-- | Lift a computation from an arrow to one with an added environment.---- Typical usage in arrow notation:---- > proc p -> ...-- > (|liftReader cmd|)liftReader::a'eb->aeb-- | Elimination of a state reader from a computation,-- taking a value for the state.---- Typical usage in arrow notation:---- > proc p -> ...-- > (|elimReader cmd|) envelimReader::aeb->a'(e,r)b-- | Adding a 'Control.Arrow.Transformer.Writer.WriterArrow' to an-- arrow type, but not necessarily as the outer arrow transformer.---- Typically a composite arrow type is built by applying a series-- of arrow transformer to a base arrow (usually either a function-- arrow or a 'Kleisli' arrow. One can add a transformer to the-- top of this stack using the 'Control.Arrow.Transformer.lift'-- method of the 'Control.Arrow.Transformer.ArrowTransformer' class,-- or remove a state transformer from the top of the stack using the-- 'Control.Arrow.Transformer.Writer.runWriter' encapsulation operator.-- The methods of this class add and remove state transformers anywhere-- in the stack. In the instance---- > instance Arrow a => ArrowAddWriter w (ArrowWriter w a) a---- they are equivalent to 'Control.Arrow.Transformer.lift' and-- 'Control.Arrow.Transformer.Writer.runWriter' respectively.-- Instances are lifted through other transformers with---- > instance ArrowAddWriter w a a' =>-- > ArrowAddWriter w (FooArrow a) (FooArrow a')class(ArrowWriterwa,Arrowa')=>ArrowAddWriterwaa'|a->a'where-- | Lift a computation from an arrow to one with added output.---- Typical usage in arrow notation:---- > proc p -> ...-- > (|liftWriter cmd|)liftWriter::a'eb->aeb-- | Elimination of an output writer from a computation,-- providing the accumulated output.---- Typical usage in arrow notation:---- > proc p -> do-- > ...-- > (result, output) <- (|elimWriter cmd|)elimWriter::aeb->a'e(b,w)-- | Adding a 'Control.Arrow.Transformer.Error.ErrorArrow' to an-- arrow type, but not necessarily as the outer arrow transformer.---- Typically a composite arrow type is built by applying a series-- of arrow transformer to a base arrow (usually either a function-- arrow or a 'Kleisli' arrow. One can add a transformer to the-- top of this stack using the 'Control.Arrow.Transformer.lift'-- method of the 'Control.Arrow.Transformer.ArrowTransformer' class,-- or remove a state transformer from the top of the stack using the-- 'Control.Arrow.Transformer.Error.runError' encapsulation operator.-- The methods of this class add and remove state transformers anywhere-- in the stack. In the instance---- > instance Arrow a => ArrowAddError ex (ArrowError ex a) a---- they are equivalent to 'Control.Arrow.Transformer.lift' and-- 'Control.Arrow.Transformer.Error.runError' respectively.-- Instances are lifted through other transformers with---- > instance ArrowAddError ex a a' =>-- > ArrowAddError ex (FooArrow a) (FooArrow a')---- This could be combined with 'Control.Arrow.Transformer.Error.handle',-- since the resulting arrow is always the arrow of the handler.-- Separating them has the advantage of consistency with the other arrows,-- and might give more helpful type error messages.class(ArrowErrorexa,Arrowa')=>ArrowAddErrorexaa'|a->a'where-- | Lift a computation from an arrow to one with error handling.---- Typical usage in arrow notation:---- > proc p -> ...-- > (|liftError cmd|)liftError::a'eb->aeb-- | Elimination of errors from a computation,-- by completely handling any errors.---- Typical usage in arrow notation:---- > proc p -> ...-- > body `elimError` \ex -> handlerelimError::aeb->a'(e,ex)b->a'eb-- | Adding a 'Control.Arrow.Transformer.Stream.StreamArrow' to an-- arrow type, but not necessarily as the outer arrow transformer.---- Typically a composite arrow type is built by applying a series-- of arrow transformer to a base arrow (usually either a function-- arrow or a 'Kleisli' arrow. One can add a transformer to the-- top of this stack using the 'Control.Arrow.Transformer.lift'-- method of the 'Control.Arrow.Transformer.ArrowTransformer' class,-- or remove a state transformer from the top of the stack using the-- 'Control.Arrow.Transformer.Stream.runStream' encapsulation operator.-- The methods of this class add and remove state transformers anywhere-- in the stack. In the instance---- > instance Arrow a => ArrowAddStream (ArrowStream a) a---- they are equivalent to 'Control.Arrow.Transformer.lift' and-- 'Control.Arrow.Transformer.Stream.runStream' respectively.-- Instances are lifted through other transformers with---- > instance ArrowAddStream a a' =>-- > ArrowAddStream (FooArrow a) (FooArrow a')class(ArrowCircuita,Arrowa')=>ArrowAddStreamaa'|a->a'where-- | Lift a computation from an arrow to a stream processing one.---- Typical usage in arrow notation:---- > proc p -> ...-- > (|liftStream cmd|)liftStream::a'eb->aeb-- | Run a stream processor on a stream of inputs,-- obtaining a stream of outputs.---- Typical usage in arrow notation:---- > proc p -> do-- > ...-- > ys <- (|elimStream (\x -> ...)|) xs---- Here @xs@ refers to the input stream and @x@ to individual-- elements of that stream. @ys@ is bound to the output stream.elimStream::a(e,b)c->a'(e,Streamb)(Streamc)