Ah, interesting. that looks very very similar. even ends up using the same data type as mine. convergent evolution? I guess the main differences are that a plate is used for all traversal, wereas with my traversal routine a typeclass is used for traversal that decides whether to use the plate on a case by case basis. Which isn't that big of a difference really, both can work like the other just fine. Although mine was originally written with monads in mind, I have dropped that just just applicative functors so they are even converging there. The other difference seems to be that multiplates use a typeclass to 'tie' up the traversal routines to reference each other and I use direct cyclic assignment. as in, instead of declaring ops a plate I do ops = (defaultOps ops) { opHsDecl = \d -> processDecl d } So, we have the same logic, and data structures, we just decided to insert the typeclass at different spots into the framework. :) Incidentally, my next version of E core will be written with generic traversal specifically in mind. I'll run it by the list before I devote to much into it. still working on consistency proofs of the new type system. Integrating the coercions from GHCs system Fc into a stratified pure type system. John On Tue, May 13, 2014 at 9:12 AM, Roman Cheplyaka <roma@ro-che.info> wrote:
Sjoerd Visscher says:
«You might want to point him to multiplate too, that's an exact match with what he's doing. (I'm not on the jhc mailing list)» (https://twitter.com/sjoerd_visscher/status/466247707699736576)
* John Meacham <john@repetae.net> [2014-05-12 17:36:43-0700]
Before
http://repetae.net/drop/TypeSyns_old.hs
and after
http://repetae.net/drop/TypeSyns_new.hs
that's right, the work of a 550 line complicated file done in a few lines.
The magic is in FrontEnd.Syn.Traverse where I have a class that recurses over arbitrary source syntax and takes a
data HsOps m = HsOps { opHsDecl :: HsDecl -> m HsDecl, opHsExp :: HsExp -> m HsExp, opHsPat :: HsPat -> m HsPat, opHsType :: HsType -> m HsType, opHsStmt :: HsStmt -> m HsStmt }
as an argument, by recursively defining your ops by 'tying the knot' each of the routines will recurse down the others. quite handy. Now I have about 2500 lines of code to excise from FrontEnd/.
Many improvements to the front end have been put off due to the sheer amount of traversal code that has to modified for every new syntax construct. good times.
John
-- John Meacham - http://notanumber.net/ _______________________________________________ jhc mailing list jhc@haskell.org http://www.haskell.org/mailman/listinfo/jhc
-- John Meacham - http://notanumber.net/