7

我在 Haskell 中使用 Warp(可能还有 Scotty)和酸状态制作了一个相当简单的 CRUD Web 服务。

在酸性状态下,我将用户记录存储在 Data.Map 中(根据示例)。我知道这些记录在创建时总是完整的,所以我不需要用很多 MaybeS 来获得资格。但是,在更新用户时,客户端可能会选择发送部分 json 对象,其中仅填充一些字段。

表示这一点的惯用方式是什么?我是否应该在所有可选键PartialUser前面有一个数据声明FullUser,没有MaybeS,而一个与MaybeS完全相同,并让aeson自动为后者派生编码和解码,最后编写我自己的类型更新函数:: FullUser -> PartialUser -> FullUser?

它不会有太多代码,但感觉有点难看,并且有点违反 DRY。它应该是 Web 服务器中的一项常见任务,所以也许它已经普遍解决了(可能使用 TH)?

我意识到我可以只存储 json 字符串并始终检查丢失的键,这使它稍微笨拙但更多的未来证明模式更改,但我仍然想知道如何以“类型安全”的方式进行操作。

编辑:或者也许我应该只有 FullUser 并使用 aeson-lens 从 FullUser 和 json 字符串编写一个简单的更新函数?

4

1 回答 1

8

惯用的 Haskell 尽可能多地进行静态检查。您应该始终从是否可以用静态检查替换动态检查的角度来处理您的问题。这基本上就是使以下关于 Haskell 的陈述非常接近现实的原因:“如果它编译,它就可以工作”。所以绝对是使用纯 JSON 的“不”。

您的解决方案FullUserPartialUser正确的。尽管我建议采用不同的命名方法:User并且UserJSON- 这样您就可以获得非常具有描述性和合理性的含义。

然而,Aeson 有一个小问题:生成的实例还不支持解析缺失的字段(请就这个问题投票)。因此,您必须手动定义实例。

于 2013-03-04T21:21:02.723 回答