我想创建一个配置字典,这样Haskell就可以像TOML一样使用。为此,我创建了“字典”结构
Dictionary a
= Section [(String, Dictionary a)]
| Point a
key @ dictionary = Section [(key, dictionary)
key |= value = Section [(key, Point value)]
现在通过半群,我可以合并两个字典来创建一个新字典:
example_configuration =
"resolution" @ "width" |= 1920
<> "resolution" @ "height" |= 1080
但我认为总是必须通过半群运算符进行组合是有噪音的。
最初,我想为字典实现 Monad,这样我就可以使用 do 块。但单子自然需要允许改变旧的价值观。这是我不想要的。有没有办法为另一个运算符而不是绑定创建自定义块符号(就像这样做)?也许是这样的:
example_configuration = combine
"resolution"@"width" |= 1920
"resolution"@"height" |= 1080
8
2 个回答
2
您可以通过将任何幺半群包装在 中,或者仅添加在数据结构中只使用一次的类型参数,将其转换为单子:
data Dictionary a r
= Section [(String, Dictionary a ())] r
| Point a r
instance Monad (Dictionary a) where
return = Section []
Section ls q >>= f = Section ls () <> f q --ish, some type matching is required
然后你就可以使用普通do
语法
example_configuration :: Dictionary Int ()
example_configuration = do
"resolution"@"width" |= 1920
"resolution"@"height" |= 1080
这是一个好主意吗?有争议的。当然可以说,这只是滥用do
语法来实现一些非常非一元的东西。另一方面,滥用这种语法实际上非常方便,特别是因为它通常允许省略括号。事实上,出于这个原因,我有时会使用根本do
不是单子的值– 只要块中只有一个语句,就不需要单子运算符,并且只需充当括号,在缩进时自动关闭回落到之前的水平。仍然被滥用,但非常有用。这样做的一个例子是,例如我用它来用 Haskell 写我的整个博士论文。do
do
然而,对于配置文件,我观点,即使用 Haskell 或另一种图灵完备的语言不是一个好主意,而是更好地使用像这样的专用语言。
|
您可以do
对 的元组实例使用表示法Monad
。
key @ dictionary = (Section [(key, fst dictionary)], ())
key |= value = (Section [(key, Point value)], ())
exampleConfiguration = fst $ do
"resolution" @ "width" |= 1920
"resolution" @ "height" |= 1080
2
-
2偏离主题,但实际上
@
只要您小心处理空格,作为运算符就可以很好地工作。我相信TypeApplications
,打开扩展后,它x@y
是一种模式,x @y
是一种类型应用程序,并且x @ y
是在操作员调用中。
– -
@KABuhr 已修复,谢谢!我在本地测试中确实对空格不够小心。
–
|
–
–
–
a
未使用 – 您真的需要它吗?)–
do
为此“(ab)使用”符号,但这通常是通过列表而不是do
符号来完成的。–
|