【Mac OS X 10.10】Haskell + Yesod + Heroku で webアプリ 1/3

### 14/12/02 現在最新の情報です.

そろそろHaskellでwebアプリの一本でも作りたくなる季節ですよね.

![Screenshot 2014-12-01 18.40.02.png](https://qiita-image-store.s3.amazonaws.com/0/30440/6a165c16-ee93-b16d-fcf1-4c0cae52f44c.png)


（画像はYesodでwebアプリのひな形を作った時に出てくる謎のアスキアート、Haskell界隈にはこいう不可解なものが多くてステキ）

Haskell + Yesod + Heroku でwebアプリを作る事を「HYH」と言うらしいですよ（適当）

今回は環境構築編です. 次はアプリケーション構築法、最後にデプロイ法を書きます.

# GHC
GHC ... Haskellのコンパイラで一番有名でYesodが唯一サポートしている. 今なら（いつでも）もれなくインタプリタをついてくる

`hsenv` などもあるにはありますが、作者がさぼっていますしおすすめは出来ません.

後述する`Stackage` + `cabal sandbox` + `cabal freeze` がベストプラクティスだと思います.

（[Yesodの公式ブログでもyesod-platformを非推奨にして上記の方法をおすすめしています。](http://www.yesodweb.com/blog/2014/08/deprecating-yesod-platform)）



てことでghcはHomebrewで入れる.（14/12/02現在　最新版7.8.3になっている事を確認）

    $ brew install ghc

これでコンパイラー(ghc)とインタプリタ(ghci) ゲット.



# cabal
cabal ... Haskellのビルドツール. Rubyの`Bundler`, Node.jsの`npm` 的なアレ

以前までは`Haskell-Platform`で入れていたと思うのですけど、

最近は依存解消に`cabal sandbox`を使うのが主流ぽいので`cabal` だけ入れるのがよいかと.

（依存は避ける限り避けるのがHaskell道. でなければすぐ依存の闇に捕まります.）


バイナリを配っているので持ってきて解凍. `/tmp` に移動してるのはゴミファイルを残すのが嫌なだけなので必須ではない.

(14/12/02現在最新版. cabal 1.20.0.1)

    $ cd /tmp
    $ wget https://www.haskell.org/cabal/release/cabal-install-1.20.0.3/cabal-1.20.0.3-x86_64-apple-darwin-mavericks.tar.gz

`wget` が無い人は`brew install wget` とかまあよしなに.

解凍する. 

    $ tar jxf cabal-1.20.0.3-x86_64-apple-darwin-mavericks.tar.gz

解凍したやつの`build/cabal/` にバイナリがいる. 

    $ cd ./dist/build/cabal
    $ ./cabal update
    $ ./cabal install cabal-install

（結構長い. 僕の場合５分くらい）

### パスを通す
`~/.cabal/bin` にパスを通す必要があります. ご自身のシェルにあわせてよしなに

    $ echo 'export PATH=$HOME/.cabal/bin:$PATH' >> ~/.zshrc
    $ which cabal
      ~/.cabal/bin/cabal

これで`cabal`コマンドが使えるようになりました！

[hackage](http://hackage.haskell.org/)（Haskellパッケージの中央管理サイト）からよしなに取ってこれます.


# Stackage + sandbox + freeze
Haskellの世界では未だに依存地獄が至る所に潜んでいて試行錯誤が続けられている.

Stackage...統合ビルドのテストを通ったバージョンが指定されたパッケージのリストをくれる.

sandbox...プロジェクト単位にパッケージを独立して管理出来るcabalの機能.

freeze...依存先の依存先は知り得なくバージョンが範囲指定のままだとヤバいのでバージョンを固めるcabalの機能

この３つを駆使して依存と戦うのが現代的なHaskell道.

## Stackage

ともあれ`cabal update ` をキメる.

    $ cabal update

`~/.cabal/config` を開いて`remote-repo: hackag(ry` となっている行を


> remote-repo: stackage-2014-11-26-ghc78hp-exc:http://www.stackage.org/snapshot/2014-11-26-ghc78hp-exc

↑こいつに変えましょう（14/12/02現在最新）.　再度 `cabal update ` をキメる.

    $ cabal update

これで`cabal install` で取ってくる先が `Stackage` という依存解消がなされたリストになりました.

# Yesod

[Github](https://github.com/yesodweb/yesod)

割とフルスタックなHaskell製のwebフレームワーク. もっとコンパクトなScotty（Sinatraぽい）のとか結構色々ある.

yesodとalexとhappyを入れる. alexとhappyはHaskellのレクサーとパーサーで一番有名なやつ.

    $ cabal install yesod-bin alex happy

（かなり長い. お茶でも入れた方が良さそう）

（１０分くらい経過）

`yesod init` をキメる.

    $  yesod init

対話形式で質問に答える.DBはローカルならSqliteでおk


* プロジェクト名はキャメルケース（e.g. TestApp）

![Screenshot 2014-12-01 18.40.02.png](https://qiita-image-store.s3.amazonaws.com/0/30440/7b3414d9-1e7d-1000-bc69-97fcfc44e90c.png)

ひな形が出来たぽい.

    $  cd [プロジェクト名（対話形式のところで答えたもの）]
    
パッケージをインストール

    $  cabal install -j --enable-tests --max-backjumps=-1 --reorder-goals

    $  yesod devel

# 約束の地、http://localhost:3000/へ

ようやく辿りつきました. http://localhost:3000/

![Screenshot 2014-12-01 19.47.54.png](https://qiita-image-store.s3.amazonaws.com/0/30440/5e1900d3-cd05-0a33-811e-2f57ecb26f11.png)

fooo↑↑

# 依存関係でエラーが出たら

エラーメッセージでググってどうしようも無かった時に使える呪文を書いておきます.

`rm -rf ~/.ghc; rm -rf ~/.cabal; brew uninstall ghc`

つまり最初からやり直すのがいいです. （Haskellの依存の闇はやばい）