to +sjoerd visscher
Maybe you can help with something I am trying to do, I'd like to
parameterize on a traversable over the input as well as the output so,
something like
where Traversable t and Applicative f
current plate definition
data Ops f = Ops { Â
opDecl :: Decl -> f Decl, Â Â
opExp  :: Exp -> f Exp
}
data OpsT t f = Ops {
opDeclT :: t Decl -> f (t Decl)
opExpT :: t Exp -> f (t Exp)
}
where I can specify specify T versions, for instance, override [Decl] -> f
[Decl] but otherwise they will automatically default to
opDeclT = T.traverse opDecl
now, the above is easy to write, tieing it all up recursively and allowing
the automatic choosing of the right 'traversable' instance seems hard
without ruining encapsulation.
See http://repetae.net/repos/jhc/src/FrontEnd/Syn/Traverse.hs for a basic
attempt, everything ending with ' is an attempt at the two level idea here.
John
On Tue, May 13, 2014 at 3:30 PM, John Meacham
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
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
[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/
-- John Meacham - http://notanumber.net/