2016-04-29 的 Workshop 重新開始，使用 [stack][stack] 管理開發環境，寫自己的 transpiler 。

## stack

> 「lts 是比較穩定的版本，什麼 nightly build 是他們還在 try 的版本。心臟比較大顆的可以試試看。」

行前先預習一下 stack 基本操作：

```
stack new my-project
cd my-project
stack setup
stack build
stack exec my-project-exe
```

下 `stack new my-project` 時， stack 會幫忙生出整個專案目錄，包含：

```
app/
  Main.hs
src/
  Lib.hs
test/
  Spec.hs
LICENSE
Setup.hs
stack.yaml
my-project.cabal
```

除了 `stack.yaml` 外，今天要關心的只有 `my-project.cabal` 和 `Main.hs` 。

記得 Workshop 剛開始時， C 用的是 cabal 配上秘藏的工具，好在不同的 GHC 版本間切換。後來 Alex 推薦了 stack ，就轉換到 stack 上了。我一開始並不熟練，花了一段時間才搞清楚，原來有兩個檔案要注意，一個是 stack 的 `stack.yaml` ，裡面指定了 GHC 的版本、套件、架構等。我還不清楚那裡面指定的 `extra-deps:` 與 cabal 檔中的有何不同？只記得用 cabal 時手動裝本地套件很麻煩。今天 silverneko 注意到， `stack.yaml` 裡的 `packages:` 應該是用來處理本地套件的。

[stack]: http://docs.haskellstack.org/en/stable/README/

`stack.yaml` 中有個重要的設定是 `resolver:` ，可以手動改，也能在跑 `stack new my-project` 時，加上參數 `--resolver` 。例如：

```
stack new my-project --resolver lts-5.14
```

[lts-5.14][lts] 的 lts 表示 long term support ，是穩定的版本。另外還有 [nightly-2016-04-28][nightly] ，其中的 nightly 表示是 nightly bulid ，每天晚上自動編譯出來的最新版。

[lts]: https://www.stackage.org/lts-5.14
[nightly]: https://www.stackage.org/nightly-2016-04-28

---

接著下 `stack setup` ， stack 會把這個專案用的 GHC 準備好：

```
stack will use a locally installed GHC
For more information on paths, see 'stack path' and 'stack exec env'
To use this GHC and packages outside of a project, consider using:
stack ghc, stack ghci, stack runghc, or stack exec
```

訊息中也提到要使用 `ghc`, `ghci` 與 `runghc` 時，前面得加上 `stack` 。

再來使用 `stack bulid` 編譯，最後下 `stack exec my-project-exe` ，就能看到輸出：

```
someFunc
```

如果打開 `app/Main.hs` ，可以看到：

```Haskell
module Main where

import Lib

main :: IO ()
main = someFunc
```

其中 `someFunc` 來自 `src/Lib.hs` ，只做一件事：輸出 `"someFunc"` ：

```Haskell
module Lib
    ( someFunc
    ) where

someFunc :: IO ()
someFunc = putStrLn "someFunc"
```
