用类型检查实现Haskell样式的模式匹配

用类型检查实现Haskell样式的模式匹配,haskell,clojure,pattern-matching,Haskell,Clojure,Pattern Matching,我正在做一个项目,在Clojure中重现Haskell的一些特性。我已经成功地实现了Hindley-Milner类型推断,现在我正试图通过宏引入模式匹配语法。我的目标是让宏首先发出有效的Clojure代码,然后对代码进行类型检查,但我发现这很难做到。因为我对Haskell和静态类型是全新的,所以我不确定是否有一种我看不到的方法,或者这是不可能的 我正在尝试跟随,至少现在是天真的版本。我的理解是,取一个值向量(或编译时的“事件”),并将其视为堆栈。通过第一列的构造函数对模式行进行分组后,您将找到与

我正在做一个项目,在Clojure中重现Haskell的一些特性。我已经成功地实现了Hindley-Milner类型推断,现在我正试图通过宏引入模式匹配语法。我的目标是让宏首先发出有效的Clojure代码,然后对代码进行类型检查,但我发现这很难做到。因为我对Haskell和静态类型是全新的,所以我不确定是否有一种我看不到的方法,或者这是不可能的

我正在尝试跟随,至少现在是天真的版本。我的理解是,取一个值向量(或编译时的“事件”),并将其视为堆栈。通过第一列的构造函数对模式行进行分组后,您将找到与向量中第一个值的构造函数相对应的模式组。如果向量是
(v1…vn)
,并且
v1
c(a1…ak)
,其中
c
是构造函数,
a1。。。ak
是构造函数的参数,然后删除构造函数
c
并将参数与向量连接起来,创建新的向量
(a1…ak v2…vn)
,然后递归运行算法

我的问题是,如何以类型可检查的方式表示这样的向量或堆栈?同样,我的目标是让Clojure宏发出既可以处理运行时值,又可以在编译时进行类型检查的代码。我可以介绍一个中间步骤,其中第一个宏发出类型可检查但本身也是宏的代码,然后让第二个宏发出实际运行的代码。但即使这样做有效,也不太令人满意,因为这表明我无法在Haskell本身完成这样的任务。我错过什么了吗

--编辑--


我现在看到,我的困惑源于在我短暂的静态类型经验中没有遇到过这样一种情况,即我必须处理异构集合。我的问题本来可以表述得更清楚一些,但因为我一直在规划问题空间,所以我并不总是确切地知道障碍是什么,或者它与我正在处理的其他事情有什么关系。多亏了下面的评论,我相信要克服这一特殊挑战,我只需要更好地了解Haskell中处理异构集合的可用选项。这似乎是一个很好的起点。

在这个主题上有很多现有技术。您是否查看过core.match或core.typed以了解它们如何处理模式匹配和类型检查?如果不是,您应该从那里开始。core.match是否会生成一个既可以检查类型又可以在运行时计算值的决策树?我的部分目标是更好地理解Haskell。如果有人试图在Haskell中这样做,他们就没有绕过类型系统的选择。那么他们将如何实现这个算法呢?是什么让你认为Haskell类型会以完全相同的表示方式检查并发出运行代码呢?实际运行的Haskell代码基本上是C(一种称为Cmm的C方言)。类型检查的Haskell代码是扩展
type
s等之后的具体语法。在中间,Haskell码的时间主要是作为核心,它类似于具体的语法,但没有语法糖和一些其他的特点,使得它适合于程序转换。我建议您先阅读GHCs Real typechecker,然后再断言哪些操作可以执行,哪些操作不能执行。最后,问题“如何以可检查类型的方式表示这样的向量或堆栈?”似乎完全脱离上下文。你用…来表示这样一个向量。。。向量。就这样。您的typechecker没有什么特别之处,只是有一个最终的代码生成步骤,它以编写typechecker时使用的语言发出代码。代码生成步骤完全独立于涉及类型检查的步骤。因此,您关于中间步骤的想法是完全正确的,并且确实是在大量静态类型语言的编译器中完成的。我没有理论背景,所以当我遇到障碍时,我不知道这是理论上的还是我遗漏的东西。我知道Haskell是用C语言编译的,但如果您愿意,当然可以用Haskell构建编译器。关于Maranget的算法和向量,我习惯于动态类型语言,在动态类型语言中,很容易使用包含任何您想要的内容的向量,Maranget似乎采取了一种非常宽松的方法,但我不清楚如何在Haskell中表示这样的向量。