From 975e5259824fb2270d8be72765979f773417ff13 Mon Sep 17 00:00:00 2001 From: Ashley Yakeley Date: Sat, 13 Oct 2007 07:48:51 +0000 Subject: [PATCH] new Control.Compositor module The Compositor class is a superclass of Arrow. --- Control/Applicative.hs | 3 ++- Control/Arrow.hs | 26 ++++++++++++-------------- Control/Compositor.hs | 37 +++++++++++++++++++++++++++++++++++++ base.cabal | 1 + 4 files changed, 52 insertions(+), 15 deletions(-) create mode 100644 Control/Compositor.hs diff --git a/Control/Applicative.hs b/Control/Applicative.hs index c22c55d..cb76bcc 100644 --- a/Control/Applicative.hs +++ b/Control/Applicative.hs @@ -39,8 +39,9 @@ module Control.Applicative ( import Prelude #endif +import Control.Compositor import Control.Arrow - (Arrow(arr, (>>>), (&&&)), ArrowZero(zeroArrow), ArrowPlus((<+>))) + (Arrow(arr, (&&&)), ArrowZero(zeroArrow), ArrowPlus((<+>))) import Control.Monad (liftM, ap, MonadPlus(..)) import Control.Monad.Instances () import Data.Monoid (Monoid(..)) diff --git a/Control/Arrow.hs b/Control/Arrow.hs index 2710be6..a339adf 100644 --- a/Control/Arrow.hs +++ b/Control/Arrow.hs @@ -25,7 +25,7 @@ module Control.Arrow ( returnA, (^>>), (>>^), -- ** Right-to-left variants - (<<<), (<<^), (^<<), + (<<^), (^<<), -- * Monoid operations ArrowZero(..), ArrowPlus(..), -- * Conditionals @@ -40,21 +40,22 @@ import Prelude import Control.Monad import Control.Monad.Fix +import Control.Compositor infixr 5 <+> infixr 3 *** infixr 3 &&& infixr 2 +++ infixr 2 ||| -infixr 1 >>>, ^>>, >>^ -infixr 1 <<<, ^<<, <<^ +infixr 1 ^>>, >>^ +infixr 1 ^<<, <<^ -- | 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 +-- as well as 'first'. The other combinators have sensible -- default definitions, which may be overridden for efficiency. -class Arrow a where +class Compositor a => Arrow a where -- | Lift a function to an arrow: you must define either this -- or 'pure'. @@ -65,9 +66,6 @@ class Arrow a where pure :: (b -> c) -> a b c pure = arr - -- | Left-to-right composition of arrows. - (>>>) :: a b c -> a c d -> a b d - -- | Send the first component of the input through the argument -- arrow, and copy the rest unchanged to the output. first :: a b c -> a (b,d) (c,d) @@ -97,6 +95,8 @@ class Arrow a where f &&& g = arr (\b -> (b,b)) >>> f *** g {-# RULES +"identity" + arr id = identity "compose/arr" forall f g . arr f >>> arr g = arr (f >>> g) "first/arr" forall f . @@ -117,7 +117,6 @@ class Arrow a where instance Arrow (->) where arr f = f - f >>> g = g . f first f = f *** id second f = id *** f -- (f *** g) ~(x,y) = (f x, g y) @@ -128,9 +127,12 @@ instance Arrow (->) where newtype Kleisli m a b = Kleisli { runKleisli :: a -> m b } +instance Monad m => Compositor (Kleisli m) where + identity = Kleisli return + Kleisli f >>> Kleisli g = Kleisli (\b -> f b >>= g) + instance Monad m => Arrow (Kleisli m) where arr f = Kleisli (return . f) - Kleisli f >>> Kleisli g = Kleisli (\b -> f b >>= g) first (Kleisli f) = Kleisli (\ ~(b,d) -> f b >>= \c -> return (c,d)) second (Kleisli f) = Kleisli (\ ~(d,b) -> f b >>= \c -> return (d,c)) @@ -147,10 +149,6 @@ f ^>> a = arr f >>> a (>>^) :: Arrow a => a b c -> (c -> d) -> a b d a >>^ f = a >>> arr f --- | Right-to-left composition, for a better fit with arrow notation. -(<<<) :: Arrow a => a c d -> a b c -> a b d -f <<< g = g >>> f - -- | Precomposition with a pure function (right-to-left variant). (<<^) :: Arrow a => a c d -> (b -> c) -> a b d a <<^ f = a <<< arr f diff --git a/Control/Compositor.hs b/Control/Compositor.hs new file mode 100644 index 0000000..7cc6381 --- /dev/null +++ b/Control/Compositor.hs @@ -0,0 +1,37 @@ +----------------------------------------------------------------------------- +-- | +-- Module : Control.Compositor +-- Copyright : (c) Ashley Yakeley 2007 +-- License : BSD-style (see the LICENSE file in the distribution) +-- +-- Maintainer : ashley@semantic.org +-- Stability : experimental +-- Portability : portable + +module Control.Compositor where + +infixr 1 >>>, <<< + +class Compositor comp where + identity :: comp a a + + -- | Left-to-right composition + (>>>) :: comp a b -> comp b c -> comp a c + +{-# RULES +"identity/left" forall p . + identity >>> p = p +"identity/right" forall p . + p >>> identity = p +"association" forall p q r . + (p >>> q) >>> r = p >>> (q >>> r) + #-} + +instance Compositor (->) where + identity = id + p >>> q = q . p + +-- | Right-to-left composition +(<<<) :: Compositor comp => comp b c -> comp a b -> comp a c +f <<< g = g >>> f + diff --git a/base.cabal b/base.cabal index 687b04b..14bcf08 100644 --- a/base.cabal +++ b/base.cabal @@ -69,6 +69,7 @@ Library { exposed-modules: Control.Applicative, Control.Arrow, + Control.Compositor, Control.Concurrent, Control.Concurrent.Chan, Control.Concurrent.MVar, -- 1.7.10.4