I want to create a Configuration Dictionary, so Haskell can be used similar to TOML. For that purpose I have created the structure "Dictionary"
Dictionary a
= Section [(String, Dictionary a)]
| Point a
key @ dictionary = Section [(key, dictionary)
key |= value = Section [(key, Point value)]
Now via semigroups I can merge two dictionaries to create a new one:
example_configuration =
"resolution" @ "width" |= 1920
<> "resolution" @ "height" |= 1080
But I think always having to combine via the semigroup operator is noisy.
Initially, I wanted to implement Monad for dictionaries, so I could use the do block. But monads naturally need to allow transforming old values. That is something I dont want. Is there a way to create a custom block notation (like do) for another operator instead of bind? Maybe like this:
example_configuration = combine
"resolution"@"width" |= 1920
"resolution"@"height" |= 1080
You can turn any monoid into a monad, as it were, by wrapping it in
Writer, or just by adding a type argument that's used exactly once in the data structure:And then you can just use ordinary
dosyntaxIs this a good idea? Debatable. It could certainly be argued that this is just abusing
dosyntax for something quite un-monadic. On the other hand, it can actually be quite convenient to abuse this syntax, in particular because it often allows omitting paretheses. In fact, I sometimes usedoon values that aren't even monadic at all for this one reason - as long as there's only one statement in adoblock, no monad operators are needed and thedosimply acts as a paretheses that's auto-closed when indentation drops back to the previous level. Still abuse, but quite useful. An example where this is done is HaTeX, which e.g. I used for writing my entire PhD thesis in Haskell.For configuration files however I would agree with chepner that it's not a good idea to use Haskell, or another Turing-complete language, but instead better something dedicated like Dhall.