在OCaml中演示GADT的具体简单示例?

时间:2015-01-09 15:45:42

标签: ocaml

我已经在周围搜索了在OCaml 中GADT 的概念,我们为什么需要它以及何时使用它等等。

我理解GADT不仅在OCaml中,而且是一个更通用的术语。

我找到了

What are GADTs?

http://caml.inria.fr/pub/docs/manual-ocaml-400/manual021.html#toc85

http://www.reddit.com/r/ocaml/comments/1jmjwf/explain_me_gadts_like_im_5_or_like_im_an/

等,但其中一些是在Haskell中,而其他人在 no GADT GADT 之间没有很好的比较示例。

所以我想要的是一个简单而又好的具体例子,我可以看到,如果没有GADT,事情就不好了。

请问我可以吗?

2 个答案:

答案 0 :(得分:5)

GADT有两个原因。

第一个(也是最常见的一个)是关于动态类型:您可以添加一些动态类型而不会丢失静态检查。但这并不简单,但你可以确定你的类型条件将得到满足。 最简单的例子在ocaml manual中给出。 这在标准库中用于以类型安全的方式重写printf(在此之前,它是一个非常可怕的Obj.magic集合)

您可能想要使用GADT的第二个原因是,您希望在类型结构上保留一些复杂的不变量。这很难表达,你经常需要付出很多努力才能做到这一点。 好吧,我没有任何示例方便,但我曾经看到一位朋友写下AVL树的实现,如果打字系统证明平衡是正确的,这很酷。

对于更多的GADT功能及其良好的使用案例,您可以阅读Mads Hartmann的非常好的blog post

答案 1 :(得分:3)

我也在寻找GADT的良好应用,因为大多数时候,我迟早会发现它,没有它们就可以做到这一点,并且通常更清洁办法。所以,这不是一个完整的调查,只是我自己的经验。

  1. 普遍价值观,又名存在感。它们允许您创建异构容器和类型安全序列化。有关Core UnivUniv_map模块的示例,请参阅。

  2. 语法树的类型安全评估程序。这里GADT对于删除一些运行时检查很有用。

  3. Pure和类型安全的Printf implementation,已经是OCaml的一部分,也是使用GADT重写的

  4. 以下是GADT如何使用的真实生活example。在该示例中,我使用GADT来指定表关系,例如one_to_oneone_to_many等。根据所使用的关系,相应地推断出函数类型。例如,one_to_maybe_one关系,返回函数'a -> 'b optionone_to_many创建一个'a -> 'b list函数。只需创建几个不同的函数即link_one_to_onelink_one_to_many等,而不是一个函数link ~one_to:relation,即可实现同样的功能。因此,人们可以认为这种方法是可论证的。