TypeCompose 0.3 → 0.5
raw patch · 6 files changed
+126/−21 lines, 6 files
Files
- CHANGES +18/−0
- TypeCompose.cabal +3/−2
- src/Control/Compose.hs +68/−12
- src/Data/Bijection.hs +3/−6
- src/Data/Pair.hs +33/−0
- src/Data/RefMonad.hs +1/−1
CHANGES view
@@ -1,5 +1,23 @@ % TypeCompose changes +== Version 0.5 ==++* Backed out DistribM. Now that I've read "Composing Monads", I know+ there's more to it. At least four different ways, all with conflicting+ Monad instances.++== Version 0.4 ==++* pairEdit, pairEditM in Data.Pair+* build-type simple+* doc tweek DistribM & joinMM+* DistribM export & comment tweak+* DistribM and (m :. n) Monad+* Functor/Functor & Applicative/Applicative tweak+* inId2. Functor & Applicative instances for Id+* removed r->m dep in RefMonad+* doc tweak+ == Version 0.3 == * Simplified Applicative instance for g :. f
TypeCompose.cabal view
@@ -1,5 +1,5 @@ Name: TypeCompose-Version: 0.3+Version: 0.5 Synopsis: Type composition classes & instances Category: Composition, Control Description:@@ -19,6 +19,7 @@ Copyright: (c) 2007 by Conal Elliott License: BSD3 Stability: provisional+build-type: Simple Hs-Source-Dirs: src Extensions: Build-Depends: base@@ -33,4 +34,4 @@ Control.Instances Control.Compose Extra-Source-Files:-ghc-options: -O -Wall+ghc-options: -Wall
src/Control/Compose.hs view
@@ -30,6 +30,7 @@ -- * Unary\/unary composition , (:.)(..), O, biO, convO, coconvO, inO, inO2, inO3 , fmapFF, fmapCC, cofmapFC, cofmapCF+ -- , DistribM(..), joinMM -- * Type composition -- ** Unary\/binary , OO(..)@@ -44,7 +45,7 @@ -- * Type application , (:$)(..), App, biApp, inApp, inApp2 -- * Identity- , Id(..), biId, inId+ , Id(..), biId, inId, inId2 -- * Constructor pairing -- ** Unary , (:*:)(..), biProd, convProd, (***#), ($*), inProd, inProd2, inProd3@@ -59,6 +60,7 @@ ) where import Control.Applicative+-- import Control.Monad (liftM,join) import Control.Arrow hiding (pure) import Data.Monoid @@ -97,6 +99,7 @@ bicomap :: Cofunctor f => (a :<->: b) -> (f a :<->: f b) bicomap (Bi ab ba) = Bi (cofmap ba) (cofmap ab) + {---------------------------------------------------------- Type composition ----------------------------------------------------------}@@ -152,7 +155,7 @@ type O = (:.) -- Here it is, as promised.-instance ( Functor g, Functor f) => Functor (g :. f) where fmap = fmapFF+instance (Functor g, Functor f) => Functor (g :. f) where fmap = fmapFF -- | @newtype@ bijection biO :: g (f a) :<->: (g :. f) a@@ -197,8 +200,7 @@ cofmapCF :: (Cofunctor g, Functor f) => (b -> a) -> (g :. f) a -> (g :. f) b cofmapCF h (O gf) = O (cofmap (fmap h) gf) -instance ( Functor (g :. f)- , Applicative g, Applicative f) => Applicative (g :. f) where+instance (Applicative g, Applicative f) => Applicative (g :. f) where pure = O . pure . pure (<*>) = inO2 (liftA2 (<*>)) @@ -215,6 +217,41 @@ -- mappend = inO2 mappend ++{-++-- A first pass at monad composition. But now I've read "Composing+-- Monads", and I know there's more to it. At least four different ways,+-- all with conflicting Monad instances.++-- | Monad distributivity.+-- +-- TODO: what conditions are required so that @(m :. n)@ satisfies the monad laws?+class DistribM m n where+ distribM :: n (m a) -> m (n a)++instance (Monad m, Monad n, DistribM m n) => Monad (m :. n) where+ return = O . return . return+ e >>= f = joinMM (liftM f e)++-- | 'join' for @(m :. n)@+joinMM :: (Monad m, Monad n, DistribM m n) =>+ (m :. n) ((m :. n) a) -> (m :. n) a+joinMM = O . liftM join . join . liftM distribM . unO . liftM unO++-- Derivation:+-- +-- (m :. n) ((m :. n) a)+-- --> m (n (m (n a))) -- liftM unO+-- --> m (n ((m :. n) a)) -- unO+-- --> m (m (n (n a))) -- liftM distribM+-- --> m (n (n a)) -- join+-- --> m (n a) -- liftM join+-- --> (m :. n) a -- O++-}++ {---------------------------------------------------------- Unary\/binary composition ----------------------------------------------------------}@@ -230,6 +267,7 @@ -- For instance, /\ a b. f (a -> m b) =~ OO f Kleisli m + {- {----------------------------------------------------------@@ -251,7 +289,11 @@ -- @ -- newtype ListMap i o = LM ([i] -> [o]) -- @+--+-- http://www.cse.unsw.edu.au/~dons/haskell-1990-2006/msg16550.html +-- | + newtype ArrowAp (~>) f a b = ArrowAp {unArrowAp :: f a ~> f b} instance (Arrow (~>), Applicative f) => Arrow (ArrowAp (~>) f) where@@ -436,11 +478,20 @@ inId :: (a -> b) -> (Id a -> Id b) inId = (Id .).(. unId) +inId2 :: (a -> b -> c) -> (Id a -> Id b -> Id c)+inId2 f (Id a) = inId (f a)+ -- | @newtype@ bijection biId :: a :<->: Id a biId = Bi Id unId +instance Functor Id where+ fmap f = inId f +instance Applicative Id where+ pure = Id+ (<*>) = inId2 ($)+ {---------------------------------------------------------- Unary constructor pairing ----------------------------------------------------------}@@ -511,6 +562,9 @@ instance (Functor f, Functor g) => Functor (f :*: g) where fmap h = inProd (fmap h *** fmap h) +instance (Applicative f, Applicative g) => Applicative (f :*: g) where+ pure a = Prod (pure a, pure a)+ (<*>) = inProd2 (\ (f,g) (a,b) -> (f <*> a, g <*> b)) {---------------------------------------------------------- Binary constructor pairing@@ -518,18 +572,18 @@ -- | Pairing of binary type constructors newtype (f ::*:: g) a b = Prodd { unProdd :: (f a b, g a b) }- -- deriving (Show, Eq, Ord)+ deriving (Show, Eq, Ord) --- Remove the next three when GHC can derive them (6.8).+-- -- Remove the next three when GHC can derive them (6.8). -instance (Show (f a b, g a b)) => Show ((f ::*:: g) a b) where- show (Prodd p) = "Prod " ++ show p+-- instance (Show (f a b, g a b)) => Show ((f ::*:: g) a b) where+-- show (Prodd p) = "Prod " ++ show p -instance (Eq (f a b, g a b)) => Eq ((f ::*:: g) a b) where- Prodd p == Prodd q = p == q+-- instance (Eq (f a b, g a b)) => Eq ((f ::*:: g) a b) where+-- Prodd p == Prodd q = p == q -instance (Ord (f a b, g a b)) => Ord ((f ::*:: g) a b) where- Prodd p < Prodd q = p < q+-- instance (Ord (f a b, g a b)) => Ord ((f ::*:: g) a b) where+-- Prodd p < Prodd q = p < q -- | Apply binary function inside of @f :*: g@ representation. inProdd :: ((f a b, g a b) -> (f' a' b', g' a' b'))@@ -557,6 +611,8 @@ -- | Arrow-like type between type constructors (doesn't enforce @Arrow -- (~>)@ here). newtype Arrw (~>) f g a = Arrw { unArrw :: f a ~> g a } -- deriving Monoid++-- For ghc-6.6, use the "deriving" above, but for 6.8 use the "deriving" below. deriving instance Monoid (f a ~> g a) => Monoid (Arrw (~>) f g a)
src/Data/Bijection.hs view
@@ -13,12 +13,9 @@ -- Stability : experimental -- Portability : TypeOperators -- --- Bijections. See also [1], which provides a more general setting.--- --- [1]: /There and Back Again: Arrows for Invertible Programming/,--- <http://citeseer.ist.psu.edu/alimarine05there.html>.--- --- +-- Bijections. For a more general setting, see also [1]+-- /There and Back Again: Arrows for Invertible Programming/,+-- <http://citeseer.ist.psu.edu/alimarine05there.html>. ---------------------------------------------------------------------- module Data.Bijection
src/Data/Pair.hs view
@@ -26,12 +26,15 @@ , UnpairTy, Unpair(..) -- * Dual unpairings , Copair(..), copair+ -- * Misc+ , pairEdit, pairEditM ) where import Data.Monoid import Control.Arrow import Control.Applicative+import Control.Monad -- for pairEdit import Control.Compose @@ -60,6 +63,13 @@ -- instance (Monoid_f h, Copair h) => Pair h where -- pair = copair -- @+-- +-- Also, if you have a type constructor that's a 'Functor' and a 'Pair',+-- here is a way to define '(<*>)' for 'Applicative':+-- +-- @+-- rf <*> rx = uncurry ($) <$> (rf `pair` rx)+-- @ class Pair f where pair :: PairTy f -- ^ Form a pair-like value (generalizes 'zip')@@ -185,3 +195,26 @@ -- Standard instance for (Monoid_f h, Copair h) instance Pair Endo where pair = copair++++{----------------------------------------------------------+ Misc+----------------------------------------------------------}++-- | Turn a pair of sources into a source of pair-editors. See+-- <http://conal.net/blog/posts/pairs-sums-and-reactivity/>.+-- 'Functor'\/'Monoid' version. See also 'pairEditM'.++pairEdit :: (Functor m, Monoid (m ((c,d) -> (c,d)))) =>+ (m c,m d) -> m ((c,d) -> (c,d))+pairEdit (ce,de) =+ fmap (first.const) ce `mappend` fmap (second.const) de+++-- | Turn a pair of sources into a source of pair-editors. See+-- <http://conal.net/blog/posts/pairs-sums-and-reactivity/>.+-- Monad version. See also 'pairEdit'.+pairEditM :: MonadPlus m => (m c,m d) -> m ((c,d) -> (c,d))+pairEditM (ce,de) =+ liftM (first.const) ce `mplus` liftM (second.const) de
src/Data/RefMonad.hs view
@@ -28,7 +28,7 @@ ------------------------------------------------------------------------------- -- | Class of monads with references.-class Monad m => RefMonad m r | m -> r, r -> m where+class Monad m => RefMonad m r | m -> r where newRef :: a -> m (r a) readRef :: r a -> m a writeRef :: r a -> a -> m ()