太久沒寫，先回憶一下進度：

* 實作 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][DesugarClass.hs] 的作法，定義了：

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

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

而：

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

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

[DesugarClass.hs]: https://github.com/CindyLinz/Haskell.js/blob/78429a49181a15f6bdae426f17bdae722ad17141/trans/src/DesugarClass.hs
[Desugar.hs]: https://github.com/CindyLinz/Haskell.js/blob/78429a49181a15f6bdae426f17bdae722ad17141/trans/src/Desugar.hs
