最近の自分の Haskell 開発環境(Windows)

id:syocy のブログを見たので Windows で自分がどうしているかをメモしておく。

syocy.hatenablog.com

Stack

最近は ghcup があるがシェルスクリプト製で自分は PowerShell ユーザーなので stack を使っている。(ghcup はなんで Haskell 製じゃないんだ1?)

GHC 8.8 を使うには resolver は ghc-8.8 や nightly を指定する。まだ LTS にはなっていない。

エディター

エディターは Spacemacs を使っている。前は IntelliJ IDEA に HaskForce プラグインを入れて使っていたが、ソースコード量に対して線形以上に動作が遅くなっている感覚があって使わなくなってしまった。

Spacemacs の提供してる Haskell レイヤーに Happy Haskell Programming を追加して使っている。

.spacemacs.d\init.el に次のように追記している(リポジトリー)。

(defun dotspacemacs/user-config ()(add-to-list 'load-path "~/.spacemacs.d/hhp/elisp")
  (autoload 'hhp-init "hhp" nil t)
  (autoload 'hhp-debug "hhp" nil t)
  (add-hook 'haskell-mode-hook (lambda () (hhp-init))))

HHP は stack プロジェクトを考慮しないので、unveil-stack を使って、ghc コマンドが呼ばれると現在のプロジェクトの resolver が指定する ghc を呼び直すようにしている。hhpc や hhpi についても同様で stack exec -- hhpc のように呼び直している。

Spacemacs の Haskell レイヤーについてはここを、HHP の機能についてはここを参照のこと。

Makefile

Haskell プロジェクトのビルドは stack 経由だが、その他のタスク用に PowerShell 版の Make のような Psake を使っている(発音は「酒」と同じだそうだ)。

リポジトリーの全ファイルに stylish-haskell や hlint をかけたり、改行を CR/LF から LF に変換したりするのに使っている。

Task Format {
    Exec { Get-ChildItem -Filter '*.hs' -Recurse src | ForEach-Object { stack exec -- stylish-haskell -i $_.FullName } }
}

Task Lint {
    Exec { stack exec -- hlint src }
}