如何在Haskell中表达以下想法?虽然语法已完全弥补,但这正是我想要实现的目标:
编辑核心问题不在于应用逻辑本身。核心问题是如何以类型安全的方式表示JSON密钥,同时能够对它们进行参数化。简单的解决方案是为每种API返回类型设置不同的具体类型,例如{orderItems :: [OrderItem], order :: Order}
或{address :: Address, order :: Order}
或{email :: Email, customer :: Customer}
。但这些将很快重复。我希望有一个数据类型,它代表具有主键值对和辅助/支持键值对的JSON的 idea ,其中键名可以轻松更改。
下面给出的伪代码是这个想法的概括:
data IncomingJson rootname payload = (FromJson payload, ToString rootname) => IncomingJson
{
rootname :: payload
}
data OutgoingJson rootname payload sidename sidepayload = (ToJson payload, ToString rootname, ToJson sidepayload, ToString sidename) => IncomingJson
{
rootname :: payload
, sidename :: sidepayload
}
createOrder :: IncomingJson "order" NewOrder -> OutgoingJson "order" Order Nothing ()
editOrderItems :: IncomingJson "items" [OrderItem] -> OutgoingJson "items" [OrderItem] "order" Order
editOrderAddress :: IncomingJson "address" Address -> OutgoingJson "address" Address "order" Order
答案 0 :(得分:1)
(编辑:试图全面回答修订后的问题。)
下面的示例代码可能接近您想要的。此示例分别使用自定义OutgoingJSON
和IncomingJSON
实例定义ToJSON
和FromJSON
。 (我也为ToJSON
数据类型包含IncomingJSON
,但我怀疑你不需要它。)它依赖于通过短{{1}分配JSON密钥的每种数据类型实例。可以使用KeyedJSON
或其他替代方法来自动执行此操作,但这看起来既丑陋又不明智。 (你真的 希望你的JSON密钥直接与Haskell数据类型名称绑定,对吗?)
如果您加载它并查看GHC.Generics
和inExample1
的类型,它们应该符合您的预期。 outExample1
和inExample2
演示了JSON块的类型安全解析 - 如果JSON块中存在期望类型的键,则成功,如果不存在则失败。最后,inExample3
显示了如何使用所需的主键和辅助键序列化outExample1AsJSON
示例。
OutgoingJSON