<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">Hi Mario,<div class=""><br class=""></div><div class="">I had a similar itch to scratch when I first started noodling with Haskell, coming from Lisp, and wrote the following for generating enums from a convenient notation:</div><div class=""><br class=""></div><div class=""><a href="https://github.com/yesodweb/yesod/wiki/Create-String-Based-Enums-With-Template-Haskell" class="">https://github.com/yesodweb/yesod/wiki/Create-String-Based-Enums-With-Template-Haskell</a></div><div class=""><br class=""></div><div class="">It’s approaching four years old, so likely no longer works as is, but I hope it is helpful.</div><div class=""><br class=""></div><div class="">Even more than with Lisp macros, TH should be seen as a last resort. However, sometimes you gotta scratch. I was frustrated at the time that I couldn’t find any decent examples, and I specifically wanted to learn some TH - regardless of whether there was a better way available.</div><div class=""><br class=""></div><div class="">In that wiki page you’ll find code for a custom quasi quoter, and code for generating declarations. I mostly just relied on the template haskell docs:</div><div class=""><br class=""></div><div class=""><a href="https://hackage.haskell.org/package/template-haskell" class="">https://hackage.haskell.org/package/template-haskell</a></div><div class=""><br class=""></div><div class="">which I found to have everything I needed, though of course there is a lot to digest in there.</div><div class=""><br class=""></div><div class="">After gaining some familiarity, the types and functions for creating those types feel a natural match to regular Haskell source, and Q is used because otherwise your declarations would be just side effect free values, unable to affect your program.</div><div class=""><br class=""></div><div class="">For your needs, find “data Dec” in the template haskell docs, and you’ll see that `DataD` matches what you need at term level. Then take a look at `dataD`, a function that will construct your declaration, using Q.</div><div class=""><br class=""></div><div class="">Cheers,</div><div class="">Si</div><div class=""><br class=""><div><blockquote type="cite" class=""><div class="">On 28 Sep 2016, at 15:06, Mario Lang <<a href="mailto:mlang@delysid.org" class="">mlang@delysid.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div class="">Hi.<br class=""><br class="">As a long-term Lisp fan, and someone who always admired compile-time<br class="">code-generation, I wanted to at least do something simple with Template<br class="">Haskell once.<br class=""><br class="">In a small project of mine, I have this basically auto-generated data<br class="">type:<br class=""><br class="">-- Braille music code only uses the old 6-dot system.  We enumerate all<br class="">-- possible dot patterns to use the type system to avoid accidentally<br class="">-- specifying invalid dot patterns in the source code.<br class="">--<br class="">-- gen :: String<br class="">-- gen =<br class="">--     "data Braille = " ++ intercalate " | " ctors ++ " deriving (Enum, Eq)" where<br class="">--   ctors = "NoDots" : map ctorName [1..63] where<br class="">--     ctorName :: Int -> String<br class="">--     ctorName = (++) "Dot" . concatMap (show . succ) . flip filter [0..5] . testBit<br class=""><br class="">data SixDots = NoDots | Dot1 | Dot2 | Dot12 | Dot3 | Dot13 | Dot23 | Dot123<br class="">             | Dot4 | Dot14 | Dot24 | Dot124 | Dot34 | Dot134 | Dot234<br class="">             | Dot1234 | Dot5 | Dot15 | Dot25 | Dot125 | Dot35 | Dot135<br class="">             | Dot235 | Dot1235 | Dot45 | Dot145 | Dot245 | Dot1245 | Dot345<br class="">             | Dot1345 | Dot2345 | Dot12345 | Dot6 | Dot16 | Dot26 | Dot126<br class="">             | Dot36 | Dot136 | Dot236 | Dot1236 | Dot46 | Dot146 | Dot246<br class="">             | Dot1246 | Dot346 | Dot1346 | Dot2346 | Dot12346 | Dot56 | Dot156<br class="">             | Dot256 | Dot1256 | Dot356 | Dot1356 | Dot2356 | Dot12356<br class="">             | Dot456 | Dot1456 | Dot2456 | Dot12456 | Dot3456 | Dot13456<br class="">             | Dot23456 | Dot123456<br class="">             deriving (Bounded, Enum, Eq, Read, Show)<br class=""><br class="">So, while actually quite simple, this looks like an opportunity to use<br class="">Template Haskell for me.  In other words, I want to figure out what is<br class="">necessary to generate this data type with TH, instead of the gen<br class="">function that basically generates a piece of plain Haskell code.<br class=""><br class="">I have been reading "A practical Template Haskell Tutorial"[1] but I find<br class="">it a little bit too terse to actually solve this very little riddle on<br class="">my own.<br class=""><br class="">For one, I find it confusing that some TH functions return "Q Dec" while<br class="">others just return Dec.  I am aware that this is some sort of Monad for<br class="">the TH system, but I have never seen it explained anywhere.<br class=""><br class="">Also, all the examples I can find seem to be mostly focused in<br class="">generating Q Exp or similar, but I didn't really find an example<br class="">for Q Dec.<br class=""><br class="">I realize this should be simple to figure out on my own, but it<br class="">apparently is not.  I have tried to wrap my head around this on my own<br class="">at least three times now, but always stopped after an hour or two due to<br class="">frustration.  Is there some comprehensive TH documentation I haven't<br class="">seen yet?  Could you please give me enough of a head-start that I<br class="">actually manage to write something which can generate this simple data<br class="">type above?<br class=""><br class="">[1] <a href="https://wiki.haskell.org/A_practical_Template_Haskell_Tutorial" class="">https://wiki.haskell.org/A_practical_Template_Haskell_Tutorial</a><br class="">-- <br class="">CYa,<br class="">  ⡍⠁⠗⠊⠕<br class="">_______________________________________________<br class="">Beginners mailing list<br class=""><a href="mailto:Beginners@haskell.org" class="">Beginners@haskell.org</a><br class="">http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners<br class=""></div></div></blockquote></div><br class=""></div></body></html>