----------------------------------------------------------------------------- -- | -- Module : Control.Arrow -- Copyright : (c) Ross Paterson 2002 -- License : BSD-style (see the LICENSE file in the distribution) -- -- Maintainer : ross@soi.city.ac.uk -- Stability : experimental -- Portability : portable -- -- Basic arrow definitions, based on -- /Generalising Monads to Arrows/, by John Hughes, -- /Science of Computer Programming/ 37, pp67-111, May 2000. -- plus a couple of definitions ('returnA' and 'loop') from -- /A New Notation for Arrows/, by Ross Paterson, in /ICFP 2001/, -- Firenze, Italy, pp229-240. -- See these papers for the equations these combinators are expected to -- satisfy. These papers and more information on arrows can be found at -- <http://www.haskell.org/arrows/>.

moduleControl.Arrow( -- * ArrowsArrow(..),Kleisli(..), -- ** Derived combinatorsreturnA, (<<<), -- * Monoid operationsArrowZero(..),ArrowPlus(..), -- * ConditionalsArrowChoice(..), -- * Arrow applicationArrowApply(..),ArrowMonad(..),leftApp, -- * FeedbackArrowLoop(..) )whereimportPreludeimportControl.MonadimportControl.Monad.Fixinfixr5<+>infixr3***infixr3&&&infixr2+++infixr2|||infixr1>>>infixr1<<<-- | The basic arrow class. -- Any instance must define either 'arr' or 'pure' (which are synonyms), -- as well as '>>>' and 'first'. The other combinators have sensible -- default definitions, which may be overridden for efficiency.classArrowawhere-- | Lift a function to an arrow: you must define either this -- or 'pure'.arr::(b->c)->abcarr=pure-- | A synonym for 'arr': you must define one or other of them.pure::(b->c)->abcpure=arr-- | Left-to-right composition of arrows. (>>>)::abc->acd->abd-- | Send the first component of the input through the argument -- arrow, and copy the rest unchanged to the output.first::abc->a(b,d) (c,d) -- | A mirror image of 'first'. -- -- The default definition may be overridden with a more efficient -- version if desired.second::abc->a(d,b) (d,c)secondf=arrswap>>>firstf>>>arrswapwhereswap~(x,y)=(y,x) -- | Split the input between the two argument arrows and combine -- their output. Note that this is in general not a functor. -- -- The default definition may be overridden with a more efficient -- version if desired. (***)::abc->ab'c'->a(b,b') (c,c')f***g=firstf>>>secondg-- | Fanout: send the input to both argument arrows and combine -- their output. -- -- The default definition may be overridden with a more efficient -- version if desired. (&&&)::abc->abc'->ab(c,c')f&&&g=arr(\b->(b,b))>>>f***g-- Ordinary functions are arrows.instanceArrow(->)wherearrf=ff>>>g=g.ffirstf=f***idsecondf=id***f-- (f *** g) ~(x,y) = (f x, g y) -- sorry, although the above defn is fully H'98, nhc98 can't parse it. (***)fg~(x,y)=(fx,gy) -- | Kleisli arrows of a monad.newtypeKleislimab=Kleisli(a->mb)instanceMonadm=>Arrow(Kleislim)wherearrf=Kleisli(return.f)Kleislif>>>Kleislig=Kleisli(\b->fb>>=g)first(Kleislif)=Kleisli(\~(b,d)->fb>>=\c->return(c,d))second(Kleislif)=Kleisli(\~(d,b)->fb>>=\c->return(d,c)) -- | The identity arrow, which plays the role of 'return' in arrow notation.returnA::Arrowa=>abbreturnA=arrid-- | Right-to-left composition, for a better fit with arrow notation. (<<<)::Arrowa=>acd->abc->abdf<<<g=g>>>fclassArrowa=>ArrowZeroawherezeroArrow::abcinstanceMonadPlusm=>ArrowZero(Kleislim)wherezeroArrow=Kleisli(\x->mzero)classArrowZeroa=>ArrowPlusawhere(<+>)::abc->abc->abcinstanceMonadPlusm=>ArrowPlus(Kleislim)whereKleislif<+>Kleislig=Kleisli(\x->fx`mplus`gx) -- | Choice, for arrows that support it. This class underlies the -- @if@ and @case@ constructs in arrow notation. -- Any instance must define 'left'. The other combinators have sensible -- default definitions, which may be overridden for efficiency.classArrowa=>ArrowChoiceawhere-- | Feed marked inputs through the argument arrow, passing the -- rest through unchanged to the output.left::abc->a(Eitherbd) (Eithercd) -- | A mirror image of 'left'. -- -- The default definition may be overridden with a more efficient -- version if desired.right::abc->a(Eitherdb) (Eitherdc)rightf=arrmirror>>>leftf>>>arrmirrorwheremirror(Leftx)=Rightxmirror(Righty)=Lefty-- | Split the input between the two argument arrows, retagging -- and merging their outputs. -- Note that this is in general not a functor. -- -- The default definition may be overridden with a more efficient -- version if desired. (+++)::abc->ab'c'->a(Eitherbb') (Eithercc')f+++g=leftf>>>rightg-- | Fanin: Split the input between the two argument arrows and -- merge their outputs. -- -- The default definition may be overridden with a more efficient -- version if desired. (|||)::abd->acd->a(Eitherbc)df|||g=f+++g>>>arruntagwhereuntag(Leftx)=xuntag(Righty)=yinstanceArrowChoice(->)whereleftf=f+++idrightf=id+++ff+++g=(Left.f)|||(Right.g) (|||)=eitherinstanceMonadm=>ArrowChoice(Kleislim)whereleftf=f+++arridrightf=arrid+++ff+++g=(f>>>arrLeft)|||(g>>>arrRight)Kleislif|||Kleislig=Kleisli(eitherfg) -- | Some arrows allow application of arrow inputs to other inputs.classArrowa=>ArrowApplyawhereapp::a(abc,b)cinstanceArrowApply(->)whereapp(f,x)=fxinstanceMonadm=>ArrowApply(Kleislim)whereapp=Kleisli(\(Kleislif,x)->fx) -- | The 'ArrowApply' class is equivalent to 'Monad': any monad gives rise -- to a 'Kleisli' arrow, and any instance of 'ArrowApply' defines a monad.newtypeArrowApplya=>ArrowMonadab=ArrowMonad(a()b)instanceArrowApplya=>Monad(ArrowMonada)wherereturnx=ArrowMonad(arr(\z->x))ArrowMonadm>>=f=ArrowMonad(m>>>arr(\x->letArrowMonadh=fxin(h, ()))>>>app) -- | Any instance of 'ArrowApply' can be made into an instance of -- 'ArrowChoice' by defining 'left' = 'leftApp'.leftApp::ArrowApplya=>abc->a(Eitherbd) (Eithercd)leftAppf=arr((\b->(arr(\()->b)>>>f>>>arrLeft, ()))|||(\d->(arr(\()->d)>>>arrRight, ())))>>>app-- | The 'loop' operator expresses computations in which an output value is -- fed back as input, even though the computation occurs only once. -- It underlies the @rec@ value recursion construct in arrow notation.classArrowa=>ArrowLoopawhereloop::a(b,d) (c,d)->abcinstanceArrowLoop(->)whereloopfb=let(c,d)=f(b,d)incinstanceMonadFixm=>ArrowLoop(Kleislim)whereloop(Kleislif)=Kleisli(liftMfst.mfix.f')wheref'xy=f(x,sndy)

Index

(HTML for this module was generated on 2015-03-03. About the conversion tool.)