我想通过在我通常使用的语言Clojure中实现算法W来教自己Hindley-Milner类型推论。我遇到了let
推理的问题,并且我不确定我是否做错了什么,或者我期望的结果是否需要算法之外的某些东西。在Hindley-Milner中`Let`推理
基本上,使用Haskell的符号,如果我尝试推断该类型:
\a -> let b = a in b + 1
我得到这个:
Num a => t -> a
但我应该得到这样的:
Num a => a -> a
再次,我实际上是在Clojure中这样做的,但我不相信这个问题是Clojure特有的,所以我使用Haskell符号来使其更清晰。当我在Haskell中尝试时,我得到了预期的结果。
反正,我可以每let
转换成一个功能应用,例如解决特定的问题:
\a -> (\b -> b + 1) a
但后来我失去let
多态性。由于我没有任何关于HM的知识,我的问题是我在这里是否缺少某些东西,或者这只是算法的工作方式。
编辑
如果任何人有类似的问题,我想知道如何解决它,我在下面Algorith W Step By Step。在第2页的底部,它表示“有时将类型的方法扩展到列表中。”由于它对我来说听起来不是强制性的,我决定跳过那部分,稍后重新审视它。
然后,我将TypeEnv
的ftv
函数直接编译为Clojure,如下所示:(ftv (vals env))
。由于我已将ftv
作为cond
表单执行,并且没有seq
s的条款,因此它简单地返回nil
表示(vals env)
。这当然就是静态类型系统设计要捕获的那种错误!无论如何,我只是重新定义ftv
有关env
地图的条款为(reduce set/union #{} (map ftv (vals env)))
,它的工作原理。
你指出我在正确的方向。问题在于我如何处理环境中的自由类型变量。谢谢! – grandinero