Haskell记录 - 使用字符串fieldname设置/获取

时间:2013-11-06 18:50:08

标签: haskell

在许多情况下,能够通过名称​​设置/获取记录字段作为字符串是有用的(例如,将记录转换为/从命令行参数,HTTP标头,SQL查询结果,或在一个易于使用的记录中的GUI树中存储小部件等)。这些函数可以有类型

setField::String->Val->Record->Record
getField::String->Record->Val
getFieldNames::Record->[String]

其中Val可能是可以转换为其他类型的东西(字符串,glib GValue,甚至我描述的转换器here

我已经开始编写一个执行此操作的库,计划将其贡献给社区(它需要一些GHC扩展,可能包括TemplateHaskell)....

我的问题 - 这样的事情已经存在吗?有没有更好的方法从外部名称/值对填充记录?我看了一遍,找不到它。 (镜头是相关的,但不要使用字符串名称。)

我认为这很有用,但不想重新发明轮子。

1 个答案:

答案 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