haskell - Haskell 中数据传输记录的通用类型
问题描述
我想与一些远程系统(可以通过 HTTP、数据库、文件等)交换数据,因此创建数据传输对象 (DTO) - 基本上,可以轻松序列化和反序列化的记录。第二步,我想将这些 DTO 映射到我的域对象。
所有 DTO 都有一个 ID 字段(例如,技术主键、消息标识符或文件名)。因为这是一种通用模式,所以我尝试以通用类型来捕捉它。这是我的第一次尝试:
data DtoShell = DtoShell
{ id :: UUID
, dto :: Dto}
data Dto
= MyDto1 ConcreteDto1
| MyDto2 ConcreteDto2
| ...
这样,与处理任意 DTO 相关的函数,因此只需要 ID,可以处理DtoShell
唯一但不需要关心内部的实际数据。特定于特定 DTO 的功能可以使用它。在这两者之间,必须有一些“调度程序”函数在具体类型上进行模式匹配并选择适当的函数——例如,将具体 DTO 映射到其相应的域类型。
但是,这个方案很难扩展——如果有新的ConcreteDto3
,我需要更改上面的代码,并且我需要更改“调度程序”功能。
我确实看到这似乎代表了一些更基本的问题(表达问题?我不是 CS 专业的......)。在我的搜索中,我遇到了潜在的解决方案:幻象类型、存在类型,以及最重要的类型类。但是我对 Haskell 和一般抽象 CS 的熟练程度还不够,无法评估每种方法的优缺点。因此,我有两个问题:
- 是否有一种普遍的、公认的做法或模式来模拟这种“可识别的记录”?例如,在访问关系数据库时。
- 是否有一个资源(书籍、论文、教程)可以比较不同的数据抽象方法?
解决方案
为什么不直接创建一个参数化多态信封?
data Envelope a = Envelope { eid :: UUID, edata :: a } deriving (Eq, Show, Functor)
这基本上只是一个专门的对(双元组),所以你让它成为所有类型类(,)
的实例。在这里,我Functor
使用DeriveFunctor
语言扩展使其成为一个实例。
推荐阅读
- c# - 保存商店物品列表并统一加载
- python - 有没有办法在同一个图中将两个地图绘制为子图?
- javascript - 当状态为“有货”时从类别中删除产品
- push-notification - Google 发送推送通知的 IP 范围是多少?
- bash - 如果字符串匹配使用grep如何grep和打印整个第一行
- ios - Swift AVFoundation 子类化 AVAsset
- sql-server - 为什么 Azure SQL Server 连接器在插入行时询问我具有默认值的列的值?
- react-native - React Native Maps - 显示UserLocation不起作用
- angular - 将参数传递给Angular服务中的函数(可观察对象)?
- ag-grid - api.getSelectedNodes() 不参考网格配置