A lot of (but not all of) what you end up getting from Lisp macros ends up being not needed to be implemented with macros in Haskell anyway.
instance Foo Bar where
quux = quuxifyBar -- terrible example
Now, you want to follow the same pattern to declare "Foo Baz", "Foo Quux" and "Foo CannedAir". I hope you like copying and pasting, because that's how you do it without Template Haksell.In Lisp, it would be a simple matter of writing a macro, like this:
(defmacro make-my-type-thing (type)
`(instance Foo ,type
((quux (x) (,(intern (format nil "quuxify-~A" type)) x)))))
Then you can: (eval-when (:compile-toplevel)
(loop for i in '(Bar Baz Quux CannedAir)
do (make-my-type-thing i)))
Yes, the example is very contrived, and yes, Haskell ships with a lot of abstractions to make this case very uncommon. But in Haskell, you just can't treat your code as data -- it's code."seems" and "heard" is the best you can do? Try it, and you'll find that it's very easy to meta-program in Haskell, even without macros.