关于你的问题2(如何在Haskell 98中编码GADT用例),你可能想看看2006年的这篇论文:Sulzmann和Wang:GADTless programming in Haskell 98。
就像你指的OCaml工作一样,这个工作通过一个相等类型来分解GADTs。有多种方法可以定义相等类型;他们使用类似于OCaml的Leibniz平等形式,它允许通过* -> *
类型的任何类型运算符的应用来进行替换。
根据给定类型检查器有关GADT均等的原因,这可能不足以涵盖GADT的所有示例:检查器可能实现不一定由此定义捕获的平等推理规则。例如,a*b = c*d
意味着a = c
和b = d
:如果仅应用类型构造函数* -> *
,则不会出现此分解形式。在2010年后期,Oleg discussed如何使用类型族通过莱布尼兹等式应用“类型解构器”,获得此定义的分解属性 - 但当然这又是在Haskell 98之外。
这是要记住的内容类型系统设计师:您的语言是否完整适用于莱布尼茨平等,因为它可以表达专业平等问题解决者可以做什么?
即使您找到足够表达的相等类型的编码,您也会遇到非常实用的便利问题:当您使用GADT时,从类型注释推断等同见证的所有用法。有了这个明确的编码,你就有更多的工作要做。
最后(不是双关语),很多GADTs的使用情况可以同样受到tagless-final embeddings(再由奥列格)表示,该IIRC往往可以在Haskell 98. blog post由马丁·斯滕贝亨做到这一点穿上点在其答复评论中有这种精神,但Oleg已经大大改进了这项技术。
@ is7s:我该怎么做?目前我用选项'-98'运行拥抱。 – Pteromys
拥抱者 - GHC特定的语言扩展在Hugs中不可用。 –