<html><head><meta http-equiv="Content-Type" content="text/html; charset=us-ascii"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class="">This pattern is quite common; even so common that over the years many systems have been constructed to support this way of programming. The original term was Attribute Grammars, a term invented by Donald Knuth.<div class=""><br class=""></div><div class="">The <a href="http://hackage.haskell.org/package/uuagc" class="">http://hackage.haskell.org/package/uuagc</a> system supports programming in this way in Haskell; it allows you to compose the semantics of an AST in a compositional way. The Utrecht Haskell compiler was built with it.</div><div class=""><br class=""></div><div class="">If you do not want to use a separate system you may want to use the embedding of attribute grammars in Haskell; a bit more cumbersome, but interesting since the completeness of the attribute grammar is checked using the Haskell type system:</div><div class=""><br class=""></div><div class=""><a href="http://hackage.haskell.org/package/AspectAG" class="">http://hackage.haskell.org/package/AspectAG</a></div><div class=""><br class=""></div><div class="">The thesis of Marcos Viera describes the underlying system in great detail: <a href="https://dspace.library.uu.nl/handle/1874/269786" class="">https://dspace.library.uu.nl/handle/1874/269786</a></div><div class=""><br class=""></div><div class="">Best,</div><div class=""> Doaitse</div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><br class=""><div><br class=""><blockquote type="cite" class=""><div class="">Op 13 feb. 2018, om 1:38  heeft Mikhail Baykov <<a href="mailto:manpacket@gmail.com" class="">manpacket@gmail.com</a>> het volgende geschreven:</div><br class="Apple-interchange-newline"><div class=""><div class="">recursion-schemes package might do the trick. I wrote TH for it and<br class="">somebody took care of getting it merged in. It should simplify some of<br class=""> this boilerplate.<br class=""><br class=""><blockquote type="cite" class=""><br class="">I am looking for a solution to get rid of this silly boilerplate:<br class=""><br class="">eval :: Ord var => Map var Bool -> Proposition var -> Bool<br class="">eval ctx prop = evalP $ fmap (ctx Map.!) prop<br class="">  where<br class="">    evalP = \case<br class="">        Var b -> b<br class="">        Not q -> not $ evalP q<br class="">        And p q -> evalP p && evalP q<br class="">        Or p q -> evalP p || evalP q<br class="">        If p q -> evalP p ==> evalP q<br class="">        Iff p q -> evalP p == evalP q<br class=""><br class="">What I would like to do in essence is to replace the data constructors like so:<br class=""><br class="">-- Not valid Haskell!! Can't pattern match on constructor only...<br class="">magic = \case<br class="">    Var -> id<br class="">    Not -> not<br class="">    And -> (&&)<br class="">    Or -> (||)<br class="">    If -> (==>)<br class="">    Iff -> (==)<br class=""><br class="">compile = transformAST magic $ fmap (\case 'P' -> False; 'Q' -> True)<br class=""><br class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class="">compile (Iff (Not (And (Var 'P') (Var 'Q'))) (Or (Not (Var 'P')) (Not (Var 'Q'))))<br class=""></blockquote></blockquote></blockquote>            ((==) (not ((&&) (id True) (id False))) ((||) (not (id True)) (not (id False))))<br class=""><br class="">Note how the compiled expression exactly mirrors the AST, so there should be some meta programming technique for this.<br class=""><br class="">Does anyone have an idea how I can achieve this?<br class=""><br class="">The full source code is here: <a href="https://gist.github.com/vimuel/7dcb8a9f1d2b7b72f020d66ec4157d7b" class="">https://gist.github.com/vimuel/7dcb8a9f1d2b7b72f020d66ec4157d7b</a><br class=""></blockquote>_______________________________________________<br class="">Haskell-Cafe mailing list<br class="">To (un)subscribe, modify options or view archives go to:<br class=""><a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe" class="">http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe</a><br class="">Only members subscribed via the mailman list are allowed to post.</div></div></blockquote></div><br class=""></div></body></html>