Ada*_*ent 15 serialization ocaml haskell
具有某种反射/内省规范的语言的巨大好处之一是可以从各种来源自动构建对象.
例如,在Java中,我可以使用相同的对象来持久化到db(使用Hibernate),序列化为XML(使用JAXB),以及序列化为JSON(json-lib).您可以在Ruby和Python中执行相同的操作,通常也遵循一些简单的Java属性或注释规则.
因此,我不需要很多"域转移对象".我可以专注于我正在工作的领域.
它似乎在像Haskell和Ocaml这样非常严格的FP中,这是不可能的.特别是Haskell.我唯一看到的是进行某种预处理或元编程(ocaml).只是接受你必须从底部向上进行所有转换吗?
换句话说,您必须做很多无聊的工作才能将haskell中的数据类型转换为JSON/XML/DB Row对象,然后再转换回数据对象.
C. *_*ann 28
我不能和OCaml说话,但我要说Haskell的主要困难是反序列化需要提前知道类型 -没有通用的方法从格式中进行机械反序列化,弄清楚结果值是什么,以及从那里开始,尽可能使用不健全或动态类型系统的语言.
抛开类型问题,有各种方法在Haskell中序列化数据:
内置类型Read
/ Show
(de)将代数数据类型和大多数内置类型序列化为字符串.表现良好的实例通常应该read . show
等同于id
,并且结果show
可以解析为构造序列化值的Haskell源代码.
可以在Hackage上找到各种序列化包; 通常这些要求要序列化的类型是某个类型类的实例,该包提供大多数内置类型的实例.有时它们只需要一个自动派生的类型实现,反射元编程Data
类的实例(它的迷人完全限定名称Data.Data.Data
),或者提供模板Haskell代码来自动生成实例.
对于真正不寻常的序列化格式 - 或者像前面提到的那样创建自己的软件包 - 人们可以获得最大的锤子,可以选择"大哥" Read
和Show
解析和漂亮打印.两者都有许多软件包,虽然起初可能听起来令人生畏,但在Haskell中,解析和漂亮打印实际上是非常轻松的.
浏览Hackage表明已经存在各种格式的序列化包,包括二进制数据,JSON,YAML和XML,虽然我没有使用它们,所以我无法亲自证明它们的工作情况.这是一个非详尽的列表,可以帮助您入门:
ByteString
的ByteString
s唯一的另一个问题是,不可避免地,并非所有类型都可以序列化 - 如果没有别的,我怀疑你将很难序列化多态类型,存在类型和函数.
对于它的价值,我认为在OCaml中找到的预处理器解决方案(例如sexplib,binprot和json-wheel等)非常棒(我认为人们使用Template Haskell做非常相似的事情).它比反射效率高得多,也可以自然地调整到各种类型.如果您不喜欢给定类型foo的自动生成的序列化程序,您可以随时编写自己的序列化程序,并且它非常适合包含foo作为组件的类型的自动生成的序列化程序.
唯一的缺点是你需要学习camlp4为自己编写其中一个.但是,一旦将构建系统设置为使用预处理器,使用它们就非常容易.它就像添加with sexp
到类型定义的末尾一样简单:
type t = { foo: int; bar: float }
with sexp
Run Code Online (Sandbox Code Playgroud)
现在你有了你的序列化器.
你自找的
做很多无聊的工作,将haskell中的数据类型转换为JSON/XML/DB Row对象,然后再转换回数据对象.
在Haskell中有许多方法可以序列化和反序列化数据类型.你可以用,例如,
每个包经常/通常带有宏或派生机制,以允许您例如派生JSON.例如,对于Data.Binary,请参阅前面的答案:Erask在Haskell中的term_to_binary?
一般的答案是:我们在Haskell中有很多很好的序列化包,我们倾向于使用现有的类'derived''基础结构(使用泛型或模板Haskell宏来进行实际派生).