我在Haskell中使用Warp(可能是Scotty)和酸状态制作一个相当简单的CRUD Web服务。
在酸状态下,我将用户记录存储在Data.Map中(根据this示例)。我知道这些记录在创建时总是完整的,因此我不需要使用很多MaybeS。但是,在更新用户时,客户端可能会选择发送部分json对象,只填充一些字段。
代表这个的惯用方法是什么?我应该有一个数据声明,FullUser,没有MaybeS和一个与所有可选键,PartialUser前面的MaybeS完全相同,让aeson自动导出后者的编码和解码,最后编写我自己的类型的更新函数:: FullUser - > PartialUser - > FullUser?
代码不会太多,但感觉有点难看,而且它有点违反了DRY。它应该是Web服务器中的常见任务,所以也许它已经被一般地解决了(可能是TH)?
我意识到我可以存储json字符串并始终检查缺少的密钥,使其略显笨拙,但更多的未来模式更改,但我仍然想知道如何在“类型安全”中执行此操作方式。
编辑: 或者我应该只使用FullUser并使用aeson-lens从FullUser和json字符串中编写一个简单的更新函数?
答案 0 :(得分:7)
惯用语Haskell正在进行尽可能多的静态检查。您应该始终从是否可以用静态替换动态检查的角度来解决您的问题。这基本上是使得关于Haskell的以下陈述非常接近现实的原因:“如果它编译,它就有效”。因此使用普通JSON肯定是“不”。
FullUser
和PartialUser
的解决方案是正确的。虽然我建议采用不同的命名方法:User
和UserJSON
- 这样您就可以获得非常具有描述性和合理性的含义。
然而,Aeson存在一个小问题:生成的实例don't yet support parsing missing fields(请在问题上投票)。因此,您必须手动定义实例。