caasih.net

Re: Build Your Own Haskell Compiler #1.0

太久沒寫,先回憶一下進度:

  • 實作 desugar 的骨幹, 走訪整個 syntax tree
    (可以定義一個 class, 然後把所有的 syntax node type 加進 instance;
    或是為每一個 syntax node type 定義一個不一樣的函數名的作法也可以;
    也可以兩種都有...)

  • 定義自己的 monad 來攜帶未來要加的資料結構, 讓這個骨幹的運行是在這個 monad 裡
    (使用 mtl 的 Control.Monad.State 也可以)

一直聽不懂 desugar 的骨幹是什麼,只記得要把資料存在 monad 的 context 中,但對於何時修改 context 中的資料,還有該 monad 的 type 該長什麼樣子,一點概念都沒有。

這次乖乖讀 LYaH ,才知道 value constructor 和 type constructor 的差別、才知道他們本來長什麼樣子。例如平常寫 data Maybe a = Nothing | Just a ,其中 Maybe 是 type constructor ,它的 type 是 * -> * ,而 NothingJust 是 value constructor ,,它們的 type 是 Maybe aa -> Maybe a

它們都是 function !它們都是 function ! 它們都是 function !

寫成 GADT 更清楚(謝謝 petercommand 介紹 KindSignatures ):

data Maybe :: * -> * where
  Nothing :: Maybe a
  Just a :: a -> Just a

了解這件事,之後才懂得靠 (<$>)(<*>) 在拜訪 AST 時,記錄下資訊。


回到坑裡,坑主所謂:

可以定義一個 class, 然後把所有的 syntax node type 加進 instance

指的是現在 DesugarClass.hs 的作法,定義了:

class Monad m => Desugarable m a where
  desugar :: a -> m a

那傳說中五百多行的 Desugar.hs 在做的事情,就是為 Annotated.Syntax 下每個 data 實作 desugar

而:

或是為每一個 syntax node type 定義一個不一樣的函數名的作法也可以

指的應該是較早的作法,也就是 transpiler 剛開始時,靠 Template Haskell 生出來的那些 deIfName :: Name -> NamedeIfOp :: Op -> Op

Isaac Huang 發佈於