-- * Arrow application
ArrowApply(..), ArrowMonad(..), leftApp,
-- * Feedback
- ArrowLoop(..)
+ ArrowLoop(..),
+
+ (>>>), (<<<) -- reexported
) where
import Prelude hiding (id,(.))
-import qualified Prelude
import Control.Monad
import Control.Monad.Fix
infixr 1 ^<<, <<^
-- | The basic arrow class.
--- Any instance must define either 'arr' or 'pure' (which are synonyms),
--- as well as 'first'. The other combinators have sensible
--- default definitions, which may be overridden for efficiency.
+--
+-- Minimal complete definition: 'arr' and 'first'.
+--
+-- The other combinators have sensible default definitions,
+-- which may be overridden for efficiency.
class Category a => Arrow a where
- -- | Lift a function to an arrow: you must define either this
- -- or 'pure'.
+ -- | Lift a function to an arrow.
arr :: (b -> c) -> a b c
- arr = pure
-
- -- | A synonym for 'arr': you must define one or other of them.
- pure :: (b -> c) -> a b c
- pure = arr
-- | Send the first component of the input through the argument
-- arrow, and copy the rest unchanged to the output.
f &&& g = arr (\b -> (b,b)) >>> f *** g
{-# RULES
-"identity"
- arr id = id
"compose/arr" forall f g .
(arr f) . (arr g) = arr (f . g)
"first/arr" forall f .
zeroArrow :: a b c
instance MonadPlus m => ArrowZero (Kleisli m) where
- zeroArrow = Kleisli (\x -> mzero)
+ zeroArrow = Kleisli (\_ -> mzero)
class ArrowZero a => ArrowPlus a where
(<+>) :: a b c -> a b c -> a b c
"fanin/arr" forall f g .
arr f ||| arr g = arr (f ||| g)
"compose/left" forall f g .
- left f >>> left g = left (f >>> g)
+ left f . left g = left (f . g)
"compose/right" forall f g .
- right f >>> right g = right (f >>> g)
+ right f . right g = right (f . g)
#-}
instance ArrowChoice (->) where
newtype ArrowApply a => ArrowMonad a b = ArrowMonad (a () b)
instance ArrowApply a => Monad (ArrowMonad a) where
- return x = ArrowMonad (arr (\z -> x))
+ return x = ArrowMonad (arr (\_ -> x))
ArrowMonad m >>= f = ArrowMonad (m >>>
arr (\x -> let ArrowMonad h = f x in (h, ())) >>>
app)