在许多情况下,能够通过名称设置/获取记录字段作为字符串是有用的(例如,将记录转换为/从命令行参数,HTTP标头,SQL查询结果,或在一个易于使用的记录中的GUI树中存储小部件等)。这些函数可以有类型
setField::String->Val->Record->Record
getField::String->Record->Val
getFieldNames::Record->[String]
其中Val可能是可以转换为其他类型的东西(字符串,glib GValue,甚至我描述的转换器here)
我已经开始编写一个执行此操作的库,计划将其贡献给社区(它需要一些GHC扩展,可能包括TemplateHaskell)....
我的问题 - 这样的事情已经存在吗?有没有更好的方法从外部名称/值对填充记录?我看了一遍,找不到它。 (镜头是相关的,但不要使用字符串名称。)
我认为这很有用,但不想重新发明轮子。
答案 0 :(得分:3)
您可以使用Vinyl
执行此类操作,但您仍需要创建强类型访问器。优点是类型系统包含足够的信息,以确保您永远不需要运行时处理Maybe
- 包装查找失败。
从该链接复制一些相关示例
name = Field :: "name" ::: String
age = Field :: "age" ::: Int
sleeping = Field :: "sleeping" ::: Bool
jon = name =: "jon"
<+> age =: 20
<+> sleeping =: True
type LifeForm = ["name" ::: String, "age" ::: Int, "sleeping" ::: Bool]
jon :: PlainRec LifeForm
wakeUp :: (("sleeping" ::: Bool) ∈ fields) => PlainRec fields -> PlainRec fields
wakeUp = sleeping `rPut` False
jon' = wakeUp jon
> rGet name jon'
"jon"
> rGet sleeping jon
True
> rGet sleeping jon'
False
如果您不愿意做类似于此的事情,那么您可能最终会遇到某种运行时故障,这意味着您可能会type Record = Map String Val
。