-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Lightweight generic library for mutually recursive data types. -- -- Multiplate is an alternative extension of the Uniplate/Compos core -- library to support mutally recursive datatypes in a way that is as -- powerful as Compos, as easy to use as Biplate, and more portable than -- both of them. Multiplate does not require GADTs and does not require -- multi-parameter type classes. It only requires rank 3 polymorphism. @package multiplate @version 0.0.2 -- | Suppose we are given mutually recursive data types A, -- B, and C. Here are some definitions of terms. -- -- -- --
--   data ABCPlate f = ABCPlate
--                   { fieldA :: A -> f A
--                   , fieldB :: B -> f B
--                   , fieldC :: C -> f C
--                   }
--   
-- -- Although this above is the original motivation behind multiplate,but -- you can make any structure you want into a Multiplate as long -- as you satisfy the two multiplate laws listed below. -- -- The names of the functions in this module are based on Sebastian -- Fischer's Refactoring Uniplate: -- http://www-ps.informatik.uni-kiel.de/~sebf/projects/traversal.html module Data.Generics.Multiplate -- | A plate over f consists of several fields of type A -> -- f A for various As. Projector is the type of the -- projection functions of plates. type Projector p a = forall f. p f -> a -> f a -- | A Multiplate is a constructor of kind (* -> *) -> -- * operating on Applicative functors having functions -- multiplate and mkPlate that satisfy the following two -- laws: -- --
    --
  1.  multiplate purePlate = purePlate where
    --   purePlate = mkPlate (\_ -> pure) 
  2. --
  3.  multiplate (composePlate p1 p2) =
    --   composePlate (multiplate p1) (multiplate p2)
    --   where composePlate p1 p2 = mkPlate (\proj a ->
    --   (Compose (proj p1 `fmap` proj p2 a))) 
  4. --
-- -- Note: By parametricity, it suffices for (1) to prove -- --
--   multiplate (mkPlate (\_ -> Identity)) = mkPlate (\_ -> Identity)
--   
class Multiplate p multiplate :: (Multiplate p, Applicative f) => p f -> p f mkPlate :: Multiplate p => (forall a. Projector p a -> (a -> f a)) -> p f -- | Given a natural transformation between two functors, f and -- g, and a plate over f, compose the natural -- transformation with each field of the plate. applyNaturalTransform :: Multiplate p => (forall a. f a -> g a) -> p f -> p g -- | Given an Applicative f, purePlate builds a -- plate over f whose fields are all pure. -- -- Generally purePlate is used as the base of a record update. One -- constructs the expression -- --
--   purePlate { fieldOfInterest = \a -> case a of 
--               | constructorOfInterest -> expr
--               | _                     -> pure a
--             }
--   
-- -- and this is a typical parameter that is passed to most functions in -- this library. purePlate :: (Multiplate p, Applicative f) => p f -- | Given an Alternative f, emptyPlate builds a -- plate over f whose fields are all const -- empty. -- -- Generally emptyPlate is used as the base of a record update. -- One constructs the expression -- --
--   emptyPlate { fieldOfInterest = \a -> case a of 
--                | constructorOfInterest -> expr
--                | _                     -> empty
--              }
--   
-- -- and this is a typical parameter that is passed to evalFamily -- and evalFamilyM. emptyPlate :: (Multiplate p, Alternative f) => p f -- | Given two plates over a monad m, the fields of the plate can -- be Kleisli composed (<=<) fieldwise. kleisliComposePlate :: (Multiplate p, Monad m) => p m -> p m -> p m -- | Given two plates, they can be composed fieldwise yielding the -- composite functor. composePlate :: (Multiplate p, Functor g) => p f -> p g -> p (Compose g f) -- | Given two plates with one over the Identity functor, the two -- plates can be composed fieldwise. composePlateRightId :: Multiplate p => p f -> p Identity -> p f -- | Given two plates with one over the Identity functor, the two -- plates can be composed fieldwise. composePlateLeftId :: (Multiplate p, Functor f) => p Identity -> p f -> p f -- | Given two plates with one over the Constant o -- applicative functor for a Monoid o, each field of the -- plate can be pointwise appended with mappend. appendPlate :: (Multiplate p, Monoid o) => p (Constant o) -> p (Constant o) -> p (Constant o) -- | Given a plate whose fields all return a Monoid o, -- mChildren produces a plate that returns the mconcat of -- all the children of the input. mChildren :: (Multiplate p, Monoid o) => p (Constant o) -> p (Constant o) -- | Given a plate whose fields all return a Monoid o, -- preorderFold produces a plate that returns the mconcat -- 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 :: (Multiplate p, Monoid o) => p (Constant o) -> p (Constant o) -- | Given a plate whose fields all return a Monoid o, -- preorderFold produces a plate that returns the mconcat -- 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 concatenation. postorderFold :: (Multiplate p, Monoid o) => p (Constant o) -> p (Constant o) -- | Given a plate whose fields transform each type, mapChildren -- returns a plate whose fields transform the children of the input. mapChildren :: Multiplate p => p Identity -> p Identity -- | Given a plate whose fields transform each type, mapFamily -- returns a plate whose fields transform the family of the input. The -- traversal proceeds bottom up, first transforming the families of the -- children, before finally transforming the value itself. mapFamily :: Multiplate p => p Identity -> p Identity -- | Given a plate whose fields transform each type, mapChildrenM -- returns a plate whose fields transform the children of the input. The -- processing is sequenced from the first child to the last child. mapChildrenM :: (Multiplate p, Applicative m, Monad m) => p m -> p m -- | 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 traversal. mapFamilyM :: (Multiplate p, Applicative m, Monad m) => p m -> p m -- | Given a plate whose fields maybe transforms each type, -- evalFamily 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 transformation -- succeeds then the result is re-evalFamilyed. -- -- A post-condition is that the input transform returns Nothing on -- all family members of the output, or more formally -- --
--   preorderFold (applyNaturalTransform t f) `composePlate` (evalFamily f) ⊑ purePlate
--    where
--     t :: forall a. Maybe a -> Constant All a
--     t = Constant . All . isNothing
--   
evalFamily :: Multiplate p => p Maybe -> p Identity -- | Given a plate whose fields maybe transforms each type, -- evalFamilyM 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-evalFamilyMed. evalFamilyM :: (Multiplate p, Applicative m, Monad m) => p (MaybeT m) -> p m -- | Given a plate used for evalFamily, replace returning -- Nothing with returning the input. This transforms plates -- suitable for evalFamily into plates suitable form -- mapFamily. always :: Multiplate p => p Maybe -> p Identity -- | Given a plate used for evalFamilyM, replace returning -- Nothing with returning the input. This transforms plates -- suitable for evalFamilyM into plates suitable form -- mapFamilyM. alwaysM :: (Multiplate p, Functor f) => p (MaybeT f) -> p f -- | Given a projection function for a plate over the Identity -- functor, upgrade the projection function to strip off the wrapper. traverseFor :: Multiplate p => Projector p a -> p Identity -> a -> a -- | Instantiate a projection function at a monad. traverseMFor :: (Multiplate p, Monad m) => Projector p a -> p m -> a -> m a -- | Given a projection function for a plate over the Constant -- o functor, upgrade the projection function to strip off the -- wrapper. foldFor :: Multiplate p => Projector p a -> p (Constant o) -> a -> o -- | Given a projection function for a plate over the Constant -- o functor, and a continuation for o, upgrade the -- projection function to strip off the wrapper and run the continuation. -- -- Typically the continuation simply strips off a wrapper for o. unwrapFor :: Multiplate p => (o -> b) -> Projector p a -> p (Constant o) -> a -> b -- | Given a projection function for a plate over the Constant -- (Sum n) functor, upgrade the projection function to strip -- off the wrappers. sumFor :: Multiplate p => Projector p a -> p (Constant (Sum n)) -> a -> n -- | Given a projection function for a plate over the Constant -- (Product n) functor, upgrade the projection function to -- strip off the wrappers. productFor :: Multiplate p => Projector p a -> p (Constant (Product n)) -> a -> n -- | Given a projection function for a plate over the Constant -- All functor, upgrade the projection function to strip off -- the wrappers. allFor :: Multiplate p => Projector p a -> p (Constant All) -> a -> Bool -- | Given a projection function for a plate over the Constant -- Any functor, upgrade the projection function to strip off -- the wrappers. anyFor :: Multiplate p => Projector p a -> p (Constant Any) -> a -> Bool -- | Given a projection function for a plate over the Constant -- (First n) functor, upgrade the projection function to -- strip off the wrappers. firstFor :: Multiplate p => Projector p a -> p (Constant (First b)) -> a -> Maybe b -- | Given a projection function for a plate over the Constant -- (Last n) functor, upgrade the projection function to strip -- off the wrappers. lastFor :: Multiplate p => Projector p a -> p (Constant (Last b)) -> a -> Maybe b