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 是 * -> * ,而 Nothing 和 Just 是 value constructor ,,它們的 type 是 Maybe a 和 a -> 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 -> Name 、 deIfOp :: Op -> Op 。