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
。