-
Notifications
You must be signed in to change notification settings - Fork 67
Description
Instead of doing e.g.
data Block = ...Block...
what if we did
data BlockF block = ...block...
deriving Functor
newtype Block = MkBlock (BlockF Block)
This trick allows ASTs to be extensible, among other benefits.
I generally like this approach, but I had a specific problem in mind that would benefit which I would like to share. https://github.com/obsidiansystems/dombuilder-pandoc/blob/master/src/Reflex/Dom/Builder/Pandoc.hs is some code to translate the Pandoc AST to reflex-dom "dom builder action" order to use within a website built with reflex dom.
I would like to have my own custom handling of pandoc the pandoc AST --- e.g. parsing relative URLs in links into a Route AST --- without having to copy and paste that function. But if we do the above "functored AST" approach, I can replace
block :: DomBuilder t m => Block -> m ()
with
blockF :: DomBuilder t m => BlockF a -> m ()
or
blockF :: DomBuilder t m => BlockF (m ()) -> m ()
These can be thought of as specialized versions of traverse_
or sequence_
, and they are very nice to work with!