multiplate 0.0 → 0.0.1
raw patch · 3 files changed
+24/−20 lines, 3 files
Files
- CHANGELOG +2/−0
- Data/Generics/Multiplate.hs +19/−19
- multiplate.cabal +3/−1
+ CHANGELOG view
@@ -0,0 +1,2 @@+New in version 0.0.1:+ - eta expanding definition of traverseMFor for GHC 7 compatibility
Data/Generics/Multiplate.hs view
@@ -1,5 +1,5 @@ {-# LANGUAGE RankNTypes, ScopedTypeVariables #-}--- | Suppose we are given mutually recurisve data types @A@, @B@, and @C@.+-- | Suppose we are given mutually recursive data types @A@, @B@, and @C@. -- Here are some definitions of terms. -- -- [@child@] A maximal subexpression of @A@, @B@, or @C@. @@ -16,15 +16,15 @@ -- The order is a context dependent. -- 'preorderFold' uses preorder, while 'postorderFold' and 'mapFamilyM' uses postorder. -- --- [@plate@] A plate is a record parameterized by a functor @f@ with one field of type+-- [@plate@] A plate is a record parametrized by a functor @f@ with one field of type -- @A -> f A@ for each type belonging to the mutually recursive set of types. For example, -- a plate for @A@, @B@, and @C@ would look like -- -- @ -- data ABCPlate f = ABCPlate -- { fieldA :: A -> f A--- , filedB :: B -> f B--- , filedC :: C -> f C+-- , fieldB :: B -> f B+-- , fieldC :: C -> f C -- } -- @ -- @@ -51,12 +51,12 @@ -- of each data type in the plate. -- -- This process essentially defines the semantics what the children of these data types are.- -- They don't have to literally be the syntantic children. For example, if a lanuage supports+ -- They don't have to literally be the syntactic children. For example, if a language supports -- quoted syntax, that quoted syntax behaves more like a literal than as a sub-expression.- -- Therefore, although quoted expressions may syntatically be subexpressions, the user may+ -- Therefore, although quoted expressions may syntactically be subexpressions, the user may -- chose to implement 'multiplate' so that they are not semantically considered subexpressions. multiplate :: (Applicative f) => p f -> p f- -- | Given a generic builder creating an @a -> f a@, use the buider to construct each field+ -- | Given a generic builder creating an @a -> f a@, use the builder to construct each field -- of the plate @p f@. The builder may need a little help to construct a field of type -- @a -> f a@, so to help out the builder pass it the projection function for the field -- being built.@@ -128,7 +128,7 @@ build :: Projector p a -> a -> m a build proj = (proj f1 <=< proj f2) --- | Given two plates, they can be composed fieldwise yeileding the composite functor.+-- | Given two plates, they can be composed fieldwise yielding the composite functor. composePlate :: forall p f g. (Multiplate p, Functor g) => p f -> p g -> p (Compose g f) composePlate f1 f2 = mkPlate build where@@ -168,18 +168,18 @@ -- | Given a plate whose fields all return a 'Data.Monoid.Monoid' @o@, -- 'preorderFold' produces a plate that returns the 'Data.Monoid.mconcat'--- of the familiy of the input. The input itself produces the leftmost element--- of the concatination, then this is followed by the family of the first child, then+-- of the family of the input. The input itself produces the leftmost element+-- of the concatenation, then this is followed by the family of the first child, then -- it is followed by the family of the second child, and so forth. preorderFold :: forall p o. (Multiplate p, Monoid o) => p (Constant o) -> p (Constant o) preorderFold f = f `appendPlate` multiplate (preorderFold f) -- | Given a plate whose fields all return a 'Data.Monoid.Monoid' @o@, -- 'preorderFold' produces a plate that returns the 'Data.Monoid.mconcat'--- of the familiy of the input. The concatination sequence begins with+-- of the family of the input. The concatenation sequence begins with -- the family of the first child, then -- it is followed by the family of the second child, and so forth until finally--- the input itself produces the rightmost element of the concatination.+-- the input itself produces the rightmost element of the concatenation. postorderFold :: forall p o. (Multiplate p, Monoid o) => p (Constant o) -> p (Constant o) postorderFold f = multiplate (postorderFold f) `appendPlate` f @@ -203,14 +203,14 @@ -- | Given a plate whose fields transform each type, 'mapFamilyM' -- returns a plate whose fields transform the family of the input.--- The sequencing is done in a depth-first postorder tranversal.+-- The sequencing is done in a depth-first postorder traversal. mapFamilyM :: (Multiplate p, Applicative m, Monad m) => p m -> p m mapFamilyM f = f `kleisliComposePlate` (multiplate (mapFamilyM f)) -- | Given a plate whose fields maybe transforms each type, 'evalFamily'--- returns a plate whose fields exhastively transform the family of the input.+-- returns a plate whose fields exhaustively transform the family of the input. -- The traversal proceeds bottom up, first transforming the families of--- the children. If a tranformation succeeds then the result is re-'evalFamily'ed.+-- the children. If a transformation succeeds then the result is re-'evalFamily'ed. -- -- A post-condition is that the input transform returns 'Nothing' on all family members -- of the output, or more formally@@ -225,9 +225,9 @@ evalFamily f = evalFamilyM (applyNaturalTransform (MaybeT . Identity) f) -- | Given a plate whose fields maybe transforms each type, 'evalFamilyM'--- returns a plate whose fields exhastively transform the family of the input.--- The sequencing is done in a depth-first postorder tranversal, but --- if a tranformation succeeds then the result is re-'evalFamilyM'ed.+-- returns a plate whose fields exhaustively transform the family of the input.+-- The sequencing is done in a depth-first postorder traversal, but +-- if a transformation succeeds then the result is re-'evalFamilyM'ed. evalFamilyM :: forall p m. (Multiplate p, Applicative m, Monad m) => p (MaybeT m) -> p m evalFamilyM f = go where@@ -257,7 +257,7 @@ -- | Instantiate a projection function at a monad. traverseMFor :: (Multiplate p, Monad m) => Projector p a -> p m -> a -> m a-traverseMFor = id+traverseMFor proj f = proj f -- | Given a projection function for a plate over the @'Constant' o@ functor, -- upgrade the projection function to strip off the wrapper.
multiplate.cabal view
@@ -1,5 +1,5 @@ Name: multiplate-Version: 0.0+Version: 0.0.1 Cabal-Version: >= 1.4 License: MIT License-File: LICENSE@@ -18,6 +18,8 @@ Multiplate does not require GADTs and does not require multi-parameter type classes. It only requires rank 3 polymorphism.+Tested-with: GHC == 6.12.3+data-files: CHANGELOG Library Build-Depends: base >= 3 && < 5, transformers >= 0.2 && < 0.3