我想通過在我通常使用的語言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