Get the direct children of a node. Usually using universe is more appropriate.
Moduleuniplate-1.6.13Haskell2010
Data.Generics.Uniplate.DataOnly
This module functions identically to Data.Generics.Uniplate.Data, but instead of using the standard Uniplate / Biplate classes defined in Data.Generics.Uniplate.Operations it uses a local copy.
Only use this module if you are using both Data and Direct instances in
the same project and they are conflicting.
- 1 type
- 2 classes
- 19 values
- Packageuniplate-1.6.13
- Exports22
- LanguageHaskell2010
- LicenceBSD-3-Clause
- SourceDataOnly.hs
Return the children of a type. If to == from then it returns the
original element (in contrast to children)
Return all the contexts and holes.
universe x == map fst (contexts x)
all (== x) [b a | (a,b) <- contexts x]The one depth version of contexts
children x == map fst (holes x)
all (== x) [b a | (a,b) <- holes x]Perform a fold-like computation on each value, technically a paramorphism
Rewrite by applying a rule everywhere you can. Ensures that the rule cannot be applied anywhere in the result:
propRewrite r x = all (isNothing . r) (universe (rewrite r x))Usually transform is more appropriate, but rewrite can give better
compositionality. Given two single transformations f and g, you can
construct f which performs both rewrites until a fixed point.mplus g
Applicative variant of rewrite
Transform every element in the tree, in a bottom-up manner.
For example, replacing negative literals with literals:
negLits = transform f
where f (Neg (Lit i)) = Lit (negate i)
f x = xApplicative variant of transform
Get all the children of a node, including itself and all children.
universe (Add (Val 1) (Neg (Val 2))) =
[Add (Val 1) (Neg (Val 2)), Val 1, Neg (Val 2), Val 2]This method is often combined with a list comprehension, for example:
vals x = [i | Val i <- universe x]Children are defined as the top-most items of type to starting at the root. All instances must define biplate, while descendBi and descendBiM are optional.
Methods
biplate :: from -> (Str to, Str to -> from)Return all the top most children of type
towithinfrom.If
from == tothen this function should return the root as the single child.descendBi :: (to -> to) -> from -> fromLike descend but with more general types. If
from == tothen this function does not descend. Therefore, when writing definitions it is highly unlikely that this function should be used in the recursive case. A common pattern is to first match the types using descendBi, then continue the recursion with descend.descendBiM :: Applicative m => (to -> m to) -> from -> m from
The standard Uniplate class, all operations require this. All definitions must define uniplate, while descend and descendM are optional.
Methods
uniplate :: on -> (Str on, Str on -> on)The underlying method in the class. Taking a value, the function should return all the immediate children of the same type, and a function to replace them.
Given
uniplate x = (cs, gen)csshould be aStr on, constructed ofZero,OneandTwo, containing allx's direct children of the same type asx.genshould take aStr onwith exactly the same structure ascs, and generate a new element with the children replaced.Example instance:
instance Uniplate Expr where uniplate (Val i ) = (Zero , \Zero -> Val i ) uniplate (Neg a ) = (One a , \(One a) -> Neg a ) uniplate (Add a b) = (Two (One a) (One b), \(Two (One a) (One b)) -> Add a b)descend :: (on -> on) -> on -> onPerform a transformation on all the immediate children, then combine them back. This operation allows additional information to be passed downwards, and can be used to provide a top-down transformation. This function can be defined explicitly, or can be provided by automatically in terms of uniplate.
For example, on the sample type, we could write:
descend f (Val i ) = Val i descend f (Neg a ) = Neg (f a) descend f (Add a b) = Add (f a) (f b)descendM :: Applicative m => (on -> m on) -> on -> m onApplicative variant of descend
Apply a sequence of transformations in order. This function obeys the equivalence:
transformBis [[transformer f],[transformer g],...] == transformBi f . transformBi g . ...Each item of type [Transformer] is applied in turn, right to left. Within each
[Transformer], the individual Transformer values may be interleaved.
The implementation will attempt to perform fusion, and avoid walking any part of the data structure more than necessary. To further improve performance, you may wish to partially apply the first argument, which will calculate information about the relationship between the transformations.
Wrap up a (a -> a) transformation function, to use with transformBis