packages feed

TypeCompose 0.7.0 → 0.9.14

raw patch · 16 files changed

Files

− CHANGES
@@ -1,74 +0,0 @@-% TypeCompose changes--== Version 0.5.1 ==--* Tweaked to work with ghc before and after 6.9--== 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-* Renamed type constructors "O" and "App" to "(:.)" and "(:$)".  Also-  include old names for compatibility.-* Replaced the 6.6-compatible OPTIONS pragmas with LANGUAGE-* Pair & Copair for Const-* Changed functional dependency for RefMonad--## Version 0.2 ##--+  More comments-+  Added [Data.Partial](src/Data/Partial.hs): partial values.-+  [Data.Bijection](src/Data/Bijection.hs): bijective arrows.  Used in-   [Control.Compose] for composing representation transformations.-+  Using `LANGUAGE` instead of `OPTIONS` pragmas-+  [Data.Pair](src/Data/Pair.hs) & [Data.Fun](src/Data/Fun.hs).  Classes of-   pair-like and function-like types.-+  [Data.RefMonad](src/Data/RefMonad.hs)-+  Renamed StaticArrow/Static to OO/OO-+  Now in{O,Flip,Prod,Arrw,Const}{,2,3} (i.e., `inO2` etc)-+  `Sink` type alias and `Monoid` instance.-+  `Monoid_f` and `O` instance.-+  `Arrw` type class with `Functor` & `Cofunctor` instances.-+  [Data.Title](src/Data/Title.hs): a titling class for type constructors.-   Doesn't really belong here.-+  Eliminated dependency on "mtl" package by removing a standard-   applicative instance for `ReaderT`.-+  [Data.CxMonoid](src/Data/CxMonoid.hs): context-dependent monoid-+  Type constructors `:*:`, `::*::`, & `:~>:`-+  `FunA` and `FunAble`, for convenient `Arrow` definitions.  See also `FunD` &-   `FunDble` in [DeepArrow].--## Version 0.1 ##--+  Renamed "Compose/Comp/unComp" to "O/O/unO".-+  Renamed "onComp" to "inO"-+  Renamed "mapSrc" to "mapCur", and renamed type parameter "src" to "cur",-   to avoid confusion with "Source" in Phooey's use of DataDriven.-+  Swapped argument order to dd in DataDriven.-+  Renamed "Updater" to "Action"-+  Changed the Monoid (IO a) instance in Control.Instances to use "liftA2-   mappend" instead of "(*>)".-+  Added unFlip, inFlip, inFlip2---[TypeCompose]:     http://haskell.org/haskellwiki/TypeCompose-[DeepArrow]:       http://haskell.org/haskellwiki/DeepArrow--[Control.Compose]: src/Control.Compose.hs
+ COPYING view
@@ -0,0 +1,25 @@+Copyright (c) 2009-2012 Conal Elliott+All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions+are met:+1. Redistributions of source code must retain the above copyright+   notice, this list of conditions and the following disclaimer.+2. Redistributions in binary form must reproduce the above copyright+   notice, this list of conditions and the following disclaimer in the+   documentation and/or other materials provided with the distribution.+3. The names of the authors may not be used to endorse or promote products+   derived from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.+IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.+
− Makefile
@@ -1,1 +0,0 @@-include ../cho-home-cabal-make.inc
− README
@@ -1,17 +0,0 @@-% TypeCompose--TypeCompose provides some classes & instances for forms of type-composition, as well as some modules that haven't found another home.  The-[wiki page] contains a description and links to documentation.--Please share any comments & suggestions on the [talk page] there.--You can configure, build, and install all in the usual way with Cabal-commands.--    runhaskell Setup.lhs configure-    runhaskell Setup.lhs build-    runhaskell Setup.lhs install--[wiki page]: http://haskell.org/haskellwiki/TypeCompose-[talk page]: http://haskell.org/haskellwiki/Talk:TypeCompose
− TODO
TypeCompose.cabal view
@@ -1,37 +1,44 @@ Name:                TypeCompose-Version:             0.7.0+Version:             0.9.14 Synopsis: 	     Type composition classes & instances Category:            Composition, Control+Cabal-Version:       >= 1.6 Description:   TypeCompose provides some classes & instances for forms of type   composition, as well as some modules who haven't yet found a home.   .   Please see the project wiki page: <http://haskell.org/haskellwiki/TypeCompose>   .-  &#169; 2007-2010 by Conal Elliott; BSD3 license.-Author:              Conal Elliott +  Copyright 2007-2012 by Conal Elliott; BSD3 license.+Author:              Conal Elliott Maintainer:          conal@conal.net-Homepage:            http://haskell.org/haskellwiki/TypeCompose-Package-Url:	     http://code.haskell.org/~conal/code/TypeCompose-Copyright:           (c) 2007-2010 by Conal Elliott+Homepage:            https://github.com/conal/TypeCompose+Copyright:           (c) 2007-2013 by Conal Elliott License:             BSD3+License-File:        COPYING Stability:           provisional build-type:	     Simple-Hs-Source-Dirs:      src-Extensions:          -Build-Depends:       base<5-Exposed-Modules:     -                     Data.Bijection-                     Data.CxMonoid-                     Data.RefMonad-                     Data.Pair-                     Data.Zip-                     Data.Lambda-                     Data.Title-		     Data.Partial-                     Control.Instances-                     Control.Compose-Extra-Source-Files:-ghc-options:         -Wall --- TODO: eliminate Pair or Zip+source-repository head+  type:     git+  location: git://github.com/conal/TypeCompose.git++Library+  Hs-Source-Dirs:      src+  Build-Depends:       base<5, base-orphans >= 0.5+  Exposed-Modules:+                       Data.Bijection+                       Data.CxMonoid+                       Data.RefMonad+                       Data.Pair+                       Data.Zip+                       Data.Lambda+                       Data.Title+                       Data.Partial+                       Control.Instances+                       Control.Compose+  ghc-options:         -Wall++  -- TODO: eliminate Pair or Zip++--  ghc-prof-options:    -prof -auto-all
src/Control/Compose.hs view
@@ -3,15 +3,19 @@            , TypeOperators, GeneralizedNewtypeDeriving, StandaloneDeriving            , CPP   #-}+#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 702+{-# Language DeriveGeneric #-}+#endif+#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 710+{-# Language KindSignatures, PolyKinds #-}+#endif -- For ghc 6.6 compatibility -- {-# OPTIONS -fglasgow-exts -fallow-undecidable-instances #-} -{-# OPTIONS_GHC -fno-warn-orphans #-}- ---------------------------------------------------------------------- -- | -- Module      :  Control.Compose--- Copyright   :  (c) Conal Elliott 2007+-- Copyright   :  (c) Conal Elliott 2007-2013 -- License     :  BSD3 --  -- Maintainer  :  conal@conal.net@@ -29,14 +33,15 @@   -- * Value transformers     Unop, Binop   -- * Specialized semantic editor combinators-  , result, argument, (~>)+  , result, argument, (~>), (~>*), (<~), (*<~)   -- * Contravariant functors-  , Cofunctor(..), bicomap+  , ContraFunctor(..), bicomap   -- * Unary\/unary composition-  , (:.)(..), O, biO, convO, coconvO, inO, inO2, inO3+  , (:.)(..), O, unO, biO, convO, coconvO, inO, inO2, inO3   , oPure, oFmap, oLiftA2, oLiftA3-  , fmapFF, fmapCC, cofmapFC, cofmapCF-  -- , DistribM(..), joinMM+  , fmapFF, fmapCC, contraFmapFC, contraFmapCF+  , DistribM(..), joinDistribM, bindDistribM, returnDistribM+  , joinMMT, joinComposeT   -- * Type composition   -- ** Unary\/binary   , OO(..)@@ -51,12 +56,12 @@   -- * Type application   , (:$)(..), App, biApp, inApp, inApp2   -- * Identity-  , Id(..), biId, inId, inId2+  , Id(..),unId, biId, inId, inId2   -- * Constructor pairing   -- ** Unary-  , (:*:)(..), biProd, convProd, (***#), ($*), inProd, inProd2, inProd3+  , (:*:)(..),(*:*), biProd, convProd, (***#), ($*), inProd, inProd2, inProd3   -- * Binary-  , (::*::)(..), inProdd, inProdd2+  , (::*::)(..), (*::*), inProdd, inProdd2   -- * Arrow between /two/ constructor applications   , Arrw(..), (:->:)   , biFun, convFun, inArrw, inArrw2, inArrw3@@ -65,6 +70,14 @@   , biEndo, inEndo   ) where ++#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 702+import GHC.Generics ( Generic )+#endif+#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 706+import GHC.Generics ( Generic1 )+#endif+ #if __GLASGOW_HASKELL__ >= 609 import Control.Category import Prelude hiding ((.), id)@@ -75,10 +88,12 @@                       hiding (pure) #endif +import Data.Orphans () import Data.Monoid+import qualified Data.Semigroup as Sem import Data.Foldable-import Data.Traversable import Control.Applicative+import Control.Monad (join,liftM)  -- import Test.QuickCheck -- for Endo @@ -97,9 +112,9 @@     Value transformers ----------------------------------------------------------} --- |Unary functions+-- | Unary functions type Unop  a = a -> a--- |Binary functions+-- | Binary functions type Binop a = a -> a -> a  @@ -110,40 +125,55 @@ --------------------------------------------------------------------}  -- | Add pre-processing-argument :: (a' -> a) -> ((a -> b) -> (a' -> b))+-- argument :: (a' -> a) -> ((a -> b) -> (a' -> b))+argument :: Category cat => (a' `cat` a) -> ((a `cat` b) -> (a' `cat` b)) argument = flip (.)  -- | Add post-processing-result :: (b -> b') -> ((a -> b) -> (a -> b'))+result :: Category cat => (b `cat` b') -> ((a `cat` b) -> (a `cat` b')) result = (.) -infixr 1 ~>+infixr 1 ~>, ~>*+infixl 1 <~, *<~+ -- | Add pre- and post processing-(~>) :: (a' -> a) -> (b -> b') -> ((a -> b) -> (a' -> b'))+(~>) :: Category cat =>+        (a' `cat` a) -> (b `cat` b') -> ((a `cat` b) -> (a' `cat` b')) -- (f ~> h) g = h . g . f f ~> h = result h . argument f --- More generally,--- --- (~>) :: Category (-->) => (a' --> a) -> (b --> b') -> ((a --> b) -> (a' --> b'))+(<~) :: Category cat =>+        (b `cat` b') -> (a' `cat` a) -> ((a `cat` b) -> (a' `cat` b'))+(<~) = flip (~>)  -- If I add argument back to DeepArrow, we can get a different generalization: -- --- (~>) :: DeepArrow (-->) => (a' --> a) -> (b --> b') -> ((a -> b) --> (a' -> b'))+-- (~>) :: DeepArrow cat => (a' `cat` a) -> (b `cat` b') -> ((a -> b) `cat` (a' -> b')) +-- | Like '(~>)' but specialized to functors and functions.+(~>*) :: (Functor p, Functor q) => +         (a' -> a) -> (b -> b') -> (p a -> q b) -> (p a' -> q b')+f ~>* g = fmap f ~> fmap g +(*<~) :: (Functor p, Functor q) => +         (b -> b') -> (a' -> a) -> (p a -> q b) -> (p a' -> q b')+(*<~) = flip (~>*)++-- (~>*) and (*<~) could be generalized to other categories (beside functions)+-- if we use a more general Functor, as in the "categories" package.+ {----------------------------------------------------------     Contravariant functors ----------------------------------------------------------}  -- | Contravariant functors.  often useful for /acceptors/ (consumers, -- sinks) of values.-class Cofunctor acc where-  cofmap :: (a -> b) -> (acc b -> acc a)+class ContraFunctor h where+  contraFmap :: (a -> b) -> (h b -> h a)  -- | Bijections on contravariant functors-bicomap :: Cofunctor f => (a :<->: b) -> (f a :<->: f b)-bicomap (Bi ab ba) = Bi (cofmap ba) (cofmap ab)+bicomap :: ContraFunctor f => (a :<->: b) -> (f a :<->: f b)+bicomap (Bi ab ba) = Bi (contraFmap ba) (contraFmap ab)   {----------------------------------------------------------@@ -172,13 +202,13 @@ >       { mempty_f = O mempty_f; mappend_f = inO2 mappend_f }  Similarly, there are two useful 'Functor' instances and two useful-'Cofunctor' instances.+'ContraFunctor' instances. ->     instance (  Functor g,   Functor f) => Functor (g :. f) where fmap = fmapFF->     instance (Cofunctor g, Cofunctor f) => Functor (g :. f) where fmap = fmapCC+>     instance (      Functor g,       Functor f) => Functor (g :. f) where fmap = fmapFF+>     instance (ContraFunctor g, ContraFunctor f) => Functor (g :. f) where fmap = fmapCC > ->     instance (Functor g, Cofunctor f) => Cofunctor (g :. f) where cofmap = cofmapFC->     instance (Cofunctor g, Functor f) => Cofunctor (g :. f) where cofmap = cofmapCF+>     instance (      Functor g, ContraFunctor f) => ContraFunctor (g :. f) where contraFmap = contraFmapFC+>     instance (ContraFunctor g,       Functor f) => ContraFunctor (g :. f) where contraFmap = contraFmapCF  However, it's such a bother to define the Functor instances per composition type, I've left the fmapFF case in.  If you want the fmapCC@@ -187,8 +217,26 @@ constraints, rather than just matching instance heads.  -}-newtype (g :. f) a = O { unO :: g (f a) }+#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 710+newtype ((g :: k2 -> *) :. (f :: k1 -> k2)) (a :: k1)+#else+newtype (g :. f) a+#endif+  = O (g (f a)) deriving ( Eq, Show, Ord+#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 702+                                          , Generic+#endif+#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 706+                                          , Generic1+#endif+                                          ) +-- newtype (g :. f) a = O { unO :: g (f a) } deriving Show++-- | Unwrap a '(:.)'.+unO :: (g :. f) a -> g (f a)+unO (O gfa) = gfa+ -- | Compatibility synonym type O = (:.) @@ -196,15 +244,36 @@  instance (Functor g, Functor f) => Functor (g :. f) where fmap = fmapFF +-- or+-- +--   deriving instance (Functor g, Functor f) => Functor (g :. f)+ -- These next two instances are based on suggestions from Creighton Hogg:   instance (Foldable g, Foldable f, Functor g) => Foldable (g :. f) where-  foldMap f = fold . fmap (foldMap f) . unO+  -- foldMap f = fold . fmap (foldMap f) . unO+  foldMap f = foldMap (foldMap f) . unO+  -- fold (O gfa) = fold (fold <$> gfa)+  -- fold = fold . fmap fold . unO+  fold = foldMap fold . unO+  -- I could let fold default  instance (Traversable g, Traversable f) => Traversable (g :. f) where-  sequenceA = fmap O . sequenceA . fmap sequenceA . unO-+  -- sequenceA = fmap O . sequenceA . fmap sequenceA . unO+  -- sequenceA = fmap O . traverse sequenceA . unO+  -- sequenceA = (unO ~> fmap O) (traverse sequenceA)+  -- traverse f = fmap O . traverse (traverse f) . unO+  traverse = (unO ~> fmap O) . traverse . traverse +-- traverse f+-- sequenceA . fmap f+-- sequenceA . (inO.fmap.fmap) f+-- sequenceA . inO (fmap (fmap f))+-- sequenceA . O . fmap (fmap f) . unO+-- fmap O . traverse sequenceA . unO . O . fmap (fmap f) . unO +-- fmap O . traverse sequenceA . fmap (fmap f) . unO +-- fmap O . traverse (sequenceA .  fmap f) . unO +-- fmap O . traverse (traverse f) . unO   -- instance (Functor g, Functor f) => Functor (g :. f) where --   fmap = inO.fmap.fmap@@ -217,8 +286,8 @@ convO :: Functor g => (b :<->: g c) -> (c :<->: f a) -> (b :<->: (g :. f) a) convO biG biF = biG >>> bimap biF >>> Bi O unO --- | Compose a bijection, Cofunctor style-coconvO :: Cofunctor g => (b :<->: g c) -> (c :<->: f a) -> (b :<->: (g :. f) a)+-- | Compose a bijection, ContraFunctor style+coconvO :: ContraFunctor g => (b :<->: g c) -> (c :<->: f a) -> (b :<->: (g :. f) a) coconvO biG biF = biG >>> bicomap biF >>> Bi O unO  @@ -263,25 +332,26 @@ oLiftA3 = inO3 . liftA3  - -- | Used for the @Functor :. Functor@ instance of 'Functor' fmapFF :: (  Functor g,   Functor f) => (a -> b) -> (g :. f) a -> (g :. f) b fmapFF = inO.fmap.fmap --- | Used for the @Cofunctor :. Cofunctor@ instance of 'Functor'-fmapCC :: (Cofunctor g, Cofunctor f) => (a -> b) -> (g :. f) a -> (g :. f) b-fmapCC = inO.cofmap.cofmap+-- | Used for the @ContraFunctor :. ContraFunctor@ instance of 'Functor'+fmapCC :: (ContraFunctor g, ContraFunctor f) => (a -> b) -> (g :. f) a -> (g :. f) b+fmapCC = inO.contraFmap.contraFmap --- | Used for the @Functor :. Cofunctor@ instance of 'Functor'-cofmapFC :: (Functor g, Cofunctor f) => (b -> a) -> (g :. f) a -> (g :. f) b-cofmapFC = inO.fmap.cofmap+-- | Used for the @Functor :. ContraFunctor@ instance of 'Functor'+contraFmapFC :: (Functor g, ContraFunctor f) => (b -> a) -> (g :. f) a -> (g :. f) b+contraFmapFC = inO.fmap.contraFmap --- cofmapFC h (O gf) = O (fmap (cofmap h) gf)+-- contraFmapFC h (O gf) = O (fmap (contraFmap h) gf) --- | Used for the @Cofunctor :. Functor@ instance of 'Functor'-cofmapCF :: (Cofunctor g, Functor f) => (b -> a) -> (g :. f) a -> (g :. f) b-cofmapCF h (O gf) = O (cofmap (fmap h) gf)+-- | Used for the @ContraFunctor :. Functor@ instance of 'Functor'+contraFmapCF :: (ContraFunctor g, Functor f) => (b -> a) -> (g :. f) a -> (g :. f) b+contraFmapCF = inO.contraFmap.fmap +-- contraFmapCF h (O gf) = O (contraFmap (fmap h) gf)+ instance (Applicative g, Applicative f) => Applicative (g :. f) where   pure  = O . pure . pure   (<*>) = (inO2.liftA2) (<*>)@@ -309,8 +379,6 @@   -{-- -- 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.@@ -321,44 +389,63 @@ 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+-- | A candidate 'join' for @(m :. n)@+joinDistribM :: (Monad m, Monad n, DistribM m n) =>+                (m :. n) ((m :. n) a) -> (m :. n) a+joinDistribM = O . liftM join . join . liftM distribM . (liftM.liftM) unO . unO  -- Derivation: --  --       (m :. n) ((m :. n) a)---   --> m (n (m (n a)))      -- liftM unO --   --> m (n ((m :. n) a))   -- unO+--   --> m (n (m (n a)))      -- (liftM.liftM) unO --   --> m (m (n (n a)))      -- liftM distribM --   --> m (n (n a))          -- join --   --> m (n a)              -- liftM join --   --> (m :. n) a           -- O --}+-- | A candidate '(>>=)' for @(m :. n)@+bindDistribM :: (Functor m, Functor n, Monad m, Monad n, DistribM m n) =>+                (m :. n) a -> (a -> (m :. n) b) -> (m :. n) b+mn `bindDistribM` f = joinDistribM (fmap f mn) +returnDistribM :: (Monad m, Monad n) => a -> (m :. n) a+returnDistribM = O . return . return +-- Template for specialization:+-- +-- instance (Functor m, Functor n, Monad m, Monad n, DistribM m n) +--       => Monad (m :. n) where+--   return = returnDistribM+--   (>>=)  = bindDistribM++-- | 'join'-like function for implicitly composed monads+joinMMT :: (Monad m, Monad n, Traversable n, Applicative m) =>+           m (n (m (n a))) -> m (n a)+joinMMT = fmap join . join . fmap sequenceA++-- | 'join'-like function for explicitly composed monads+joinComposeT :: (Monad m, Monad n, Traversable n, Applicative m) =>+                (m :. n) ((m :. n) a) -> (m :. n) a+joinComposeT = O . joinMMT . unO . fmap unO++ {----------------------------------------------------------     Unary\/binary composition ----------------------------------------------------------}  -- | Composition of type constructors: unary with binary.  Called -- "StaticArrow" in [1].-newtype OO f (~>) a b = OO { unOO :: f (a ~> b) }+newtype OO f j a b = OO { unOO :: f (a `j` b) }   #if __GLASGOW_HASKELL__ >= 609-instance (Applicative f, Category (~>)) => Category (OO f (~>)) where+instance (Applicative f, Category cat) => Category (OO f cat) where   id          = OO (pure id)   OO g . OO h = OO (liftA2 (.) g h) #endif -instance (Applicative f, Arrow (~>)) => Arrow (OO f (~>)) where+instance (Applicative f, Arrow arr) => Arrow (OO f arr) where #if __GLASGOW_HASKELL__ < 609   OO g >>> OO h = OO (liftA2 (>>>) g h) #endif@@ -490,39 +577,42 @@ ----------------------------------------------------------}  -- | Flip type arguments-newtype Flip (~>) b a = Flip { unFlip :: a ~> b }+newtype Flip j b a = Flip { unFlip :: a `j` b }  -- | @newtype@ bijection-biFlip :: (a ~> b) :<->: Flip (~>) b a+biFlip :: (a `j` b) :<->: Flip j b a biFlip = Bi Flip unFlip  -- Apply unary function inside of a 'Flip' representation.-inFlip :: ((a~>b) -> (a' ~~> b')) -> (Flip (~>) b a -> Flip (~~>) b' a')+inFlip :: ((a `j` b) -> (a' `k` b')) -> (Flip j b a -> Flip k b' a') inFlip = unFlip ~> Flip  -- Apply binary function inside of a 'Flip' representation.-inFlip2 :: ((a~>b) -> (a' ~~> b') -> (a'' ~~~> b''))-        -> (Flip (~>) b a -> Flip (~~>) b' a' -> Flip (~~~>) b'' a'')+inFlip2 :: ((a `j` b) -> (a' `k` b') -> (a'' `l` b''))+        -> (Flip j b a -> Flip k b' a' -> Flip l b'' a'') inFlip2 f (Flip ar) = inFlip (f ar)  -- Apply ternary function inside of a 'Flip' representation.-inFlip3 :: ((a~>b) -> (a' ~~> b') -> (a'' ~~~> b'') -> (a''' ~~~~> b'''))-        -> (Flip (~>) b a -> Flip (~~>) b' a' -> Flip (~~~>) b'' a'' -> Flip (~~~~>) b''' a''')+inFlip3 :: ((a `j` b) -> (a' `k` b') -> (a'' `l` b'') -> (a''' `m` b'''))+        -> (Flip j b a -> Flip k b' a' -> Flip l b'' a'' -> Flip m b''' a''') inFlip3 f (Flip ar) = inFlip2 (f ar) -instance Arrow (~>) => Cofunctor (Flip (~>) b) where-  cofmap h (Flip f) = Flip (arr h >>> f)+instance Arrow arr => ContraFunctor (Flip arr b) where+  contraFmap h (Flip f) = Flip (arr h >>> f) +instance (Applicative (j a), Sem.Semigroup o) => Sem.Semigroup (Flip j o a) where+  (<>) = inFlip2 (liftA2 (Sem.<>))+ -- Useful for (~>) = (->).  Maybe others.-instance (Applicative ((~>) a), Monoid o) => Monoid (Flip (~>) o a) where+instance (Applicative (j a), Monoid o) => Monoid (Flip j o a) where   mempty  = Flip (pure mempty)-  mappend = inFlip2 (liftA2 mappend)+  mappend = (<>)  -- TODO: generalize (->) to (~>) with Applicative_f (~>) instance Monoid o => Monoid_f (Flip (->) o) where   { mempty_f = mempty ; mappend_f = mappend } --- | (-> IO ()) as a 'Flip'.  A Cofunctor.+-- | (-> IO ()) as a 'Flip'.  A ContraFunctor. type OI = Flip (->) (IO ())  -- | Convert to an 'OI'.@@ -563,22 +653,42 @@ inApp2 h (App fa) = inApp (h fa)  -- Example: App IO ()+instance (Applicative f, Sem.Semigroup m) => Sem.Semigroup (App f m) where+  (<>) = inApp2 (liftA2 (Sem.<>))+ instance (Applicative f, Monoid m) => Monoid (App f m) where   mempty  =   App  (pure   mempty )-  mappend = inApp2 (liftA2 mappend)+  mappend = (<>)  --  App a `mappend` App b = App (liftA2 mappend a b)   {-----------------------------------------------------------    Identity -- TODO: eliminate in favor of Data.Traversable.Id+    Identity ----------------------------------------------------------}  -- | Identity type constructor.  Until there's a better place to find it. -- I'd use "Control.Monad.Identity", but I don't want to introduce a -- dependency on mtl just for Id.-newtype Id a = Id { unId :: a }+newtype Id a = Id a deriving ( Eq, Show, Ord+#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 702+                             , Generic+#endif+#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 706+                             , Generic1+#endif+                             ) +-- Could define record field:+-- +--   newtype Id a = Id { unId :: a } deriving Show+-- +-- but then Show is uglier.++-- Extract value from an 'Id'+unId :: Id a -> a+unId (Id a) = a+ inId :: (a -> b) -> (Id a -> Id b) inId = unId ~> Id @@ -596,6 +706,22 @@   pure  = Id   (<*>) = inId2 ($) +instance Monad Id where+  return = pure+  Id x >>= f = f x++instance Foldable Id where+  foldMap f (Id a) = f a+  -- foldMap f = f . unId+  -- foldMap = (. unId)++instance Traversable Id where+  sequenceA (Id fa) = fmap Id fa++-- Id fa :: Id (f a)+-- fa :: f a+-- fmap Id fa = f (Id a)+ {----------------------------------------------------------     Unary constructor pairing ----------------------------------------------------------}@@ -604,6 +730,10 @@ newtype (f :*: g) a = Prod { unProd :: (f a, g a) }   -- deriving (Show, Eq, Ord) +-- | Handy infix & curried 'Prod'+(*:*) :: f a -> g a -> (f :*: g) a+(*:*) = curry Prod+ -- | @newtype@ bijection biProd :: (f a, g a) :<->: (f :*: g) a biProd = Bi Prod unProd@@ -678,6 +808,10 @@ newtype (f ::*:: g) a b = Prodd { unProdd :: (f a b, g a b) }   deriving (Show, Eq, Ord) +-- | Handy infix & curried 'Prodd'+(*::*) :: f a b -> g a b -> (f ::*:: g) a b+(*::*) = curry Prodd+ -- -- 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@@ -724,47 +858,50 @@  -- | Arrow-like type between type constructors (doesn't enforce @Arrow -- (~>)@ here).-newtype Arrw (~>) f g a = Arrw { unArrw :: f a ~> g a } -- deriving Monoid+newtype Arrw j f g a = Arrw { unArrw :: f a `j` 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)+deriving instance Sem.Semigroup (f a `j` g a) => Sem.Semigroup (Arrw j f g a)+deriving instance Monoid (f a `j` g a) => Monoid (Arrw j f g a)  -- Replace with generalized bijection? --- toArrw :: Arrow (~>) => (f a ~> b) -> (c ~> g a) -> ((b ~> c) -> Arrw (~>) f g a)+-- toArrw :: Arrow j => (f a ~> b) -> (c ~> g a) -> ((b ~> c) -> Arrw j f g a) -- toArrw fromF toG h = Arrw (fromF >>> h >>> toG) --- fromArrw :: Arrow (~>) => (b ~> f a) -> (g a ~> c) -> (Arrw (~>) f g a -> (b ~> c))+-- fromArrw :: Arrow j => (b ~> f a) -> (g a ~> c) -> (Arrw j f g a -> (b ~> c)) -- fromArrw toF fromG (Arrw h') = toF >>> h' >>> fromG  -- | Apply unary function inside of @Arrw@ representation.-inArrw :: ((f a ~> g a) -> (f' a' ~> g' a'))-       -> ((Arrw (~>) f g) a -> (Arrw (~>) f' g') a')+inArrw :: ((f a `j` g a) -> (f' a' `j` g' a'))+       -> ((Arrw j f g) a -> (Arrw j f' g') a') inArrw = unArrw ~> Arrw --- | Apply binary function inside of @Arrw (~>) f g@ representation.-inArrw2 :: ((f a ~> g a) -> (f' a' ~> g' a') -> (f'' a'' ~> g'' a''))-        -> (Arrw (~>) f g a -> Arrw (~>) f' g' a' -> Arrw (~>) f'' g'' a'')+-- | Apply binary function inside of @Arrw j f g@ representation.+inArrw2 :: ((f a `j` g a) -> (f' a' `j` g' a') -> (f'' a'' `j` g'' a''))+        -> (Arrw j f g a -> Arrw j f' g' a' -> Arrw j f'' g'' a'') inArrw2 h (Arrw p) = inArrw (h p) --- | Apply ternary function inside of @Arrw (~>) f g@ representation.-inArrw3 :: ((f a ~> g a) -> (f' a' ~> g' a') -> (f'' a'' ~> g'' a'') -> (f''' a''' ~> g''' a'''))-        -> ((Arrw (~>) f g) a -> (Arrw (~>) f' g') a' -> (Arrw (~>) f'' g'') a'' -> (Arrw (~>) f''' g''') a''')+-- | Apply ternary function inside of @Arrw j f g@ representation.+inArrw3 ::+  ((f a `j` g a) -> (f' a' `j` g' a') ->+   (f'' a'' `j` g'' a'') -> (f''' a''' `j` g''' a'''))+  -> ((Arrw j f g) a -> (Arrw j f' g') a' -> (Arrw j f'' g'') a'' -> (Arrw j f''' g''') a''') inArrw3 h (Arrw p) = inArrw2 (h p) --- Functor & Cofunctor instances.  Beware use of 'arr', which is not+-- Functor & ContraFunctor instances.  Beware use of 'arr', which is not -- available for some of my favorite arrows. -instance (Arrow (~>), Cofunctor f, Functor g) => Functor (Arrw (~>) f g) where-  fmap h = inArrw $ \ fga -> arr (cofmap h) >>> fga >>> arr (fmap h)+instance (Arrow j, ContraFunctor f, Functor g) => Functor (Arrw j f g) where+  fmap h = inArrw $ \ fga -> arr (contraFmap h) >>> fga >>> arr (fmap h) -instance (Arrow (~>), Functor f, Cofunctor g) => Cofunctor (Arrw (~>) f g) where-  cofmap h = inArrw $ \ fga -> arr (fmap h) >>> fga >>> arr (cofmap h)+instance (Arrow j, Functor f, ContraFunctor g) => ContraFunctor (Arrw j f g) where+  contraFmap h = inArrw $ \ fga -> arr (fmap h) >>> fga >>> arr (contraFmap h)  -- Restated, -- ---   cofmap h = inArrw $ (arr (fmap h) >>>) . (>>> arr (cofmap h))+--   contraFmap h = inArrw $ (arr (fmap h) >>>) . (>>> arr (contraFmap h))  -- 'Arrw' specialized to functions.   type (:->:) = Arrw (->)@@ -807,9 +944,6 @@ ---- For Control.Applicative.Endo  -- deriving instance Monoid o => Monoid (Const o a)-instance Monoid o => Monoid (Const o a) where-  mempty  = Const mempty-  mappend = inConst2 mappend  -- newtype Endo a = Endo { appEndo :: a -> a } 
src/Control/Instances.hs view
@@ -1,28 +1,20 @@-{-# OPTIONS_GHC -fno-warn-orphans #-} ---------------------------------------------------------------------- -- | -- Module      :  Control.Instances -- Copyright   :  (c) Conal Elliott 2007 -- License     :  BSD3--- +-- -- Maintainer  :  conal@conal.net -- Stability   :  experimental -- Portability :  portable--- +-- -- Some (orphan) instances that belong elsewhere (where they wouldn't be orphans). -- Add the following line to get these instances--- +-- -- > import Control.Instances ()--- +-- ----------------------------------------------------------------------  module Control.Instances () where -import Data.Monoid-import Control.Applicative----- Standard instance: Applicative functor applied to monoid-instance Monoid o => Monoid (IO o) where -  mempty  = pure   mempty-  mappend = liftA2 mappend+import Data.Orphans ()
src/Data/Bijection.hs view
@@ -33,7 +33,7 @@ infixr 2 --->  -- | A type of bijective arrows-data Bijection (~>) a b = Bi { biTo :: a ~> b, biFrom :: b ~> a }+data Bijection j a b = Bi { biTo :: a `j` b, biFrom :: b `j` a }  -- | Bijective functions type a :<->: b = Bijection (->) a b@@ -41,20 +41,20 @@ -- | Bijective identity arrow.  Warning: uses 'arr' on @(~>)@.  If you -- have no 'arr', but you have a @DeepArrow@, you can instead use @Bi idA -- idA@.-idb :: Arrow (~>) => Bijection (~>) a a+idb :: Arrow j => Bijection j a a idb = Bi idA idA where idA = arr id  -- | Inverse bijection-inverse :: Bijection (~>) a b -> Bijection (~>) b a+inverse :: Bijection j a b -> Bijection j b a inverse (Bi ab ba) = Bi ba ab  #if __GLASGOW_HASKELL__ >= 609-instance Category (~>) => Category (Bijection (~>)) where+instance Category j => Category (Bijection j) where   id = Bi id id   Bi bc cb . Bi ab ba = Bi (bc . ab) (ba . cb) #endif -instance Arrow (~>) => Arrow (Bijection (~>)) where+instance Arrow j => Arrow (Bijection j) where #if __GLASGOW_HASKELL__ < 609   Bi ab ba >>> Bi bc cb = Bi (ab >>> bc) (cb >>> ba) #endif@@ -75,10 +75,15 @@ bimap (Bi ab ba) = Bi (fmap ab) (fmap ba)  -- | Bijections on arrows.-(--->) :: Arrow (~>) => Bijection (~>) a b -> Bijection (~>) c d-       -> (a ~> c) :<->: (b ~> d)+(--->) :: Arrow j => Bijection j a b -> Bijection j c d+       -> (a `j` c) :<->: (b `j` d) Bi ab ba ---> Bi cd dc = Bi (\ ac -> ba>>>ac>>>cd) (\ bd -> ab>>>bd>>>dc) +-- TODO: Rewrite (--->) via (~>).  Currently would cause a module cycle+-- +-- Bi ab ba ---> Bi cd dc = Bi (ac ~> cd) (ab ~> dc)++ -- | Apply a function in an alternative (monomorphic) representation.-inBi :: Arrow (~>) => Bijection (~>) a b -> (a ~> a) -> (b ~> b)+inBi :: Arrow j => Bijection j a b -> (a `j` a) -> (b `j` b) inBi (Bi to from) aa = from >>> aa >>> to
src/Data/CxMonoid.hs view
@@ -16,6 +16,7 @@ module Data.CxMonoid (MonoidDict, CxMonoid(..), biCxMonoid) where  import Data.Monoid (Monoid(..))+import qualified Data.Semigroup as Sem  import Data.Bijection import Data.Title@@ -30,10 +31,13 @@ biCxMonoid :: (MonoidDict a -> a) :<->: CxMonoid a biCxMonoid = Bi CxMonoid unCxMonoid +instance Sem.Semigroup (CxMonoid a) where+  CxMonoid f <> CxMonoid g  =+    CxMonoid (\ md@(_,op) -> f md `op` g md)+ instance Monoid (CxMonoid a) where   mempty = CxMonoid (\ (e,_) -> e)-  CxMonoid f `mappend` CxMonoid g  =-    CxMonoid (\ md@(_,op) -> f md `op` g md)+  mappend = (Sem.<>)  -- Exploit the function instance of 'Title' instance Title a => Title (CxMonoid a) where
src/Data/Lambda.hs view
@@ -93,13 +93,13 @@  -- | 'lambda' with 'Arrw'.  /Warning/: definition uses 'arr', so only -- use if your arrow has a working 'arr'.-arLambda :: (Arrow (~>), Unlambda f f', Lambda g g')-      => LambdaTy (Arrw (~>) f g) (Arrw (~>) f' g')+arLambda :: (Arrow j, Unlambda f f', Lambda g g')+      => LambdaTy (Arrw j f g) (Arrw j f' g') arLambda = inArrw2 $ \ fga fgb ->   arr unlambda >>> fga***fgb >>> arr (uncurry lambda) -instance (Arrow (~>), Unlambda f f', Lambda g g')-    => Lambda (Arrw (~>) f g) (Arrw (~>) f' g')+instance (Arrow j, Unlambda f f', Lambda g g')+    => Lambda (Arrw j f g) (Arrw j f' g')   where lambda = arLambda  
src/Data/Pair.hs view
@@ -95,8 +95,8 @@ -- Standard instance, e.g., (~>) = (->) -- This one requires UndecidableInstances.  Alternatively, specialize to -- (->) and other arrows as desired.-instance (Arrow (~>), Monoid_f (Flip (~>) o)) =>-  Pair (Flip (~>) o) where pair = copair+instance (Arrow j, Monoid_f (Flip j o)) =>+  Pair (Flip j o) where pair = copair  -- | Handy for 'Pair' instances apPair :: (Applicative h, Pair f) => PairTy (h :. f)@@ -108,12 +108,12 @@  -- | Pairing of 'Arrw' values.  /Warning/: definition uses 'arr', so only -- use if your arrow has a working 'arr'.-arPair :: (Arrow (~>), Unpair f, Pair g) => PairTy (Arrw (~>) f g)+arPair :: (Arrow j, Unpair f, Pair g) => PairTy (Arrw j f g) arPair = inArrw2 $ \ fga fgb ->   arr unpair >>> fga***fgb >>> arr (uncurry pair)  -- Standard instance-instance (Arrow (~>), Unpair f, Pair g) => Pair (Arrw (~>) f g)+instance (Arrow j, Unpair f, Pair g) => Pair (Arrw j f g)   where pair = arPair  instance (Pair f, Pair g) => Pair (f :*: g) where@@ -159,11 +159,11 @@ ----------------------------------------------------------}  -- | Dual to 'Unpair'.--- Especially handy for contravariant functors ('Cofunctor') .  Use this+-- Especially handy for contravariant functors ('ContraFunctor') .  Use this -- template (filling in @f@) : --  -- --- >    instance Cofunctor f => Copair f where+-- >    instance ContraFunctor f => Copair f where -- >      { cofsts = cofmap fst ; cosnds = cofmap snd }  class Copair f where@@ -175,8 +175,8 @@   cosnds = inConst id  -- Standard instance for contravariant functors-instance Arrow (~>) => Copair (Flip (~>) o) where-  { cofsts = cofmap fst ; cosnds = cofmap snd }+instance Arrow j => Copair (Flip j o) where+  { cofsts = contraFmap fst ; cosnds = contraFmap snd }  instance (Functor h, Copair f) => Copair (h :. f) where   cofsts = inO (fmap cofsts)
src/Data/Partial.hs view
@@ -1,5 +1,6 @@ {-# LANGUAGE TypeSynonymInstances #-} {-# OPTIONS_GHC -Wall #-}+{-# OPTIONS_GHC -fno-warn-orphans #-} ---------------------------------------------------------------------- -- | -- Module      :  Data.Partial@@ -13,8 +14,8 @@ -- A monoid 'Partial' of partial values.  See the [Teaser] and [Solution] blog -- posts. -- ---   [Teaser]:   <http://conal-elliott.blogspot.com/2007/07/type-for-partial-values.html>---   [Solution]: <http://conal-elliott.blogspot.com/2007/07/implementing-type-for-partial-values.html>+--   [Teaser]:   <http://conal.net/blog/posts/a-type-for-partial-values>+--   [Solution]: <http://conal.net/blog/posts/implementing-a-type-for-partial-values> --  -- Also defines a 'FunAble' instance, so that @FunA Partial@ is an arrow. ----------------------------------------------------------------------
src/Data/Title.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE FlexibleInstances, OverlappingInstances, TypeOperators, TypeSynonymInstances #-}+{-# LANGUAGE FlexibleInstances, TypeOperators, TypeSynonymInstances #-} {-# OPTIONS_GHC -Wall #-} ---------------------------------------------------------------------- -- |@@ -40,7 +40,8 @@  instance Title_f g => Title_f (g :. f) where title_f str = inO (title_f str) -instance Title_f f => Title (f a) where title = title_f+instance {-# OVERLAPPABLE #-} Title_f f => Title (f a) where+  title = title_f  instance Title String where   title ttl str = (ttl ++ suffix ++ str)
src/Data/Zip.hs view
@@ -5,7 +5,9 @@ #else {-# OPTIONS_GHC -fenable-rewrite-rules #-} #endif+{-# OPTIONS_GHC -Wno-inline-rule-shadowing #-} + ---------------------------------------------------------------------- -- | -- Module      :  Data.Zip@@ -126,8 +128,8 @@ -- Standard instance, e.g., (~>) = (->) -- This one requires UndecidableInstances.  Alternatively, specialize to -- (->) and other arrows as desired.-instance (Arrow (~>), Monoid_f (Flip (~>) o)) =>-  Zip (Flip (~>) o) where zip = cozip+instance (Arrow j, Monoid_f (Flip j o)) =>+  Zip (Flip j o) where zip = cozip  -- | Handy for 'Zip' instances apZip :: (Applicative h, Zip f) => ZipTy (h :. f)@@ -139,12 +141,12 @@  -- | Ziping of 'Arrw' values.  /Warning/: definition uses 'arr', so only -- use if your arrow has a working 'arr'.-arZip :: (Arrow (~>), Unzip f, Zip g) => ZipTy (Arrw (~>) f g)+arZip :: (Arrow j, Unzip f, Zip g) => ZipTy (Arrw j f g) arZip = inArrw2 $ \ fga fgb ->   arr unzip >>> fga***fgb >>> arr (uncurry zip)  -- Standard instance-instance (Arrow (~>), Unzip f, Zip g) => Zip (Arrw (~>) f g)+instance (Arrow j, Unzip f, Zip g) => Zip (Arrw j f g)   where zip = arZip  instance (Zip f, Zip g) => Zip (f :*: g) where@@ -206,8 +208,8 @@   cosnds = inConst id  -- Standard instance for contravariant functors-instance Arrow (~>) => Cozip (Flip (~>) o) where-  { cofsts = cofmap fst ; cosnds = cofmap snd }+instance Arrow j => Cozip (Flip j o) where+  { cofsts = contraFmap fst ; cosnds = contraFmap snd }  instance (Functor h, Cozip f) => Cozip (h :. f) where   cofsts = inO (fmap cofsts)
− wikipage.tw
@@ -1,55 +0,0 @@-[[Category:Composition]]-[[Category:Applicative]]-[[Category:Libraries]]-[[Category:Packages]]-[[Category:Type-level programming]]--== Abstract ==--'''TypeCompose''' provides some classes & instances for forms of type composition, as well as some modules that haven't found another home.--Besides this wiki page, here are more ways to find out about TypeCompose:-* Visit the [http://hackage.haskell.org/cgi-bin/hackage-scripts/package/TypeCompose Hackage page] for library documentation and to download & install.-* Or install with <tt>cabal install TypeCompose</tt>.-* Get the code repository: <tt>darcs get http://darcs.haskell.org/packages/TypeCompose</tt>.-<!--* See the [[TypeCompose/Versions| version history]].-->--== Type composition ==--The <hask>Control.Compose</hask> module includes-* Various type compositions (unary/unary, binary/unary, etc).  Most are from [http://www.soi.city.ac.uk/~ross/papers/Applicative.html Applicative Programming with Effects].  In particular, <hask>g `O` f</hask> composes functors in to functors and applicative functors (AFs) into AFs.  (In contrast, monads do not in general compose.)  Composition makes AF-based programming simple and elegant, partly because we don't need an AF counterpart to monad transformers.-* Cofunctors (contravariant functors).  Great for "consumer" types, just as functors suit "producer" (container) types.  There are several composition options.-* Type argument flip.  Handy for cofunctors: use <hask>Flip (->) o</hask>, for <hask>(-> o)</hask>.-* Constructor in pairs: <hask>(f a, g a)</hask>.-* Constructor in arrows/functions: <hask>f a ~> g a</hask>.--== Other features ==--=== Composable bijections ===--Given all the type constructors and compositions of them, I found myself writing some pretty awkward code to wrap & unwrap through multiple layers.  Composable bijections help a lot.--The <hask>Data.Bijection</hask> module is inspired by [http://citeseer.ist.psu.edu/alimarine05there.html There and Back Again: Arrows for Invertible Programming], though done here in a less general setting.--=== Pair- & function-like types ===--The <hask>Data.Zip</hask> and <hask>Data.Lambda</hask> patterns emerged while working on [[DeepArrow]] and [[Eros]].  <hask>Data.Zip</hask> generalizes <hask>zip</hask> and <hask>unzip</hask>  from <hask>[]</hask> to other functors.  It also provides variants of type <hask>f a -> f (a,b)</hask> and <hask>f a -> f (a,b)</hask>.  <hask>Data.Lambda</hask> is similar with classes for lambda-like constructions.--For example uses of <hask>Pair</hask> and <hask>Lambda</hask>, see [[TV]] and [[Eros]].--=== References ===--Monads with references.  Direct rip-off from [http://citeseer.ist.psu.edu/473734.html Global Variables in Haskell].--=== Titling ===--For giving titles to things.  I know it sounds kind of random.  More useful than I first thought.  Used in [[Phooey]], [[TV]], and [[Eros]].--=== Partial values ===--A monoid of partial values.  See the [http://conal.net/blog/posts/a-type-for-partial-values/ teaser] and [http://conal.net/blog/posts/implementing-a-type-for-partial-values/ solution] blog-posts.--=== Context-dependent monoids ===--Bit of an oddball also.  <hask>Data.CxMonoid</hask> defines a sort of meta-monoid, that can be supplied dynamically with choices of <hask>mempty</hask> and <hask>mappend</hask>.  Used in [[Phooey]] (starting with version 1.3) so that layout could be a monoid but still vary in style.