[haskell-src-exts][haskell-src-exts] 的 AST 複雜很多，會遇到放在 `Maybe` 和 `[]` 裡面的 AST 。這時要是只用 `famp` ，就會遇上把 `[Term a]` 變成 `[Desugar (Term a)]` 這種窘境。真正想得到的是 `Desugar [Term a]` ，接著才可以繼續 `(<*>)` 下去。

[haskell-src-exts]: https://hackage.haskell.org/package/haskell-src-exts-1.17.1

先把本來的 Term 改成這樣：

```
data Term a = Var a
            | Lam [a] (Term a)
            | App (Term a) [Term a]
  deriving (Show)
```

表示現在 `Lam` 可以吃多個變數。（我知道這樣不對，畢竟有 currying 就好了，但為了練習就... XD）

`desugar` 函數就變成：

```
instance Desugarable Desugar (Term a) where
  desugar (Var a) = Var <$> pure a
  desugar (Lam aList term) = Lam <$> traverse pure aList <*> desugar term
  desugar (App term termList) = App <$> desugar term <*> traverse desugar termList
```

# increase

在這個練習中，我給自己的目標是算出 term 的數量，於是得增加 `Lam <$> traverse pure aList <*> desugar term` 生出來的 `Desugar (Term a)` 中的 `info` 。

為了可以這樣寫：

```
desugar (Lam aList term) = do
  increase 1
  Lam <$> traverse pure aList <*> desugar termm
```

就得做出這樣的函數：

```
increase :: Int -> Desugar ()
increase i = D (i, ()) :: Desugar ()
```

當兩個 `Desugar a` 被 `(>>=)` 接在一起時，得把 tuple 的後面那項送給 monad 使用者，再將得出的結果中的 `info` （第一項）加在一起計數，做出新的 `Desugar a` ：

```
instance Monad Desugar where
  return = pure
  D (info, a) >>= f =
    let
      D (info', a') = f a
    in
      D (info + info', a')
```

# Monad Laws

最後檢查一下這個 monad 有沒有遵守 monad laws ：

```
return a >>= f = f a -- left identity
m >>= return = m -- right identity
(m >>= f) >>= g = m >>= (\x -> f x >>= g) -- associativity
```

在 left identity law 中， `return a` 得到的 `info` 是 `0` ，不影響 `f a` 的結果。

在 right identity law 中， `m` 帶的 `info` 會和 `return` 帶來的 `0` 加在一起，一樣不影響 `m` 。

在 associativity law 中，先完成 `m >>= f` 會把 `m` 和 `f` 帶來的 `info` 先加在一起，再加上 `g` 帶來的 `info` ；而等號右邊，會加把 `f` 和 `g` 帶來的 `info` 相加，再加上 `m` 的， `+` 自己就有結合律，故此 monad 也有。

---

拖了三個月。這段時間斷斷續續讀著 [Haskell Programming from First Principle][haskellbook] ，大概讀了四分之一。 haskell-src-exts 在這之中升到了 0.18 版，現在只有 Annotated AST ，還補上了一些 type 。十月初試著[升級看看][upgrade]，沒什麼困難，就是打字罷了。剛發現已經到了 0.19 版，不知道又改了些什麼？

[haskellbook]: http://haskellbook.com
[upgrade]: https://github.com/caasi/trans/commit/ed8cf0b2cab2bd6f581a2a453035c60ac6cd37c2

前途茫茫，越來越在意自己沒有扎實的電腦科學基礎。之前被推薦過 coursera 上的 Programming Languages, Part A ，也許是個起點。
