Haskellを書くときはstylish-haskellとhlintを使って労せずして綺麗なコードを書きましょう

3年前ぐらいからHaskellを書くときには,stylish-haskellとhlintを使ってコードを書いています.

これらを使うと,私のように,ツールに頼ってコードを書いているだけでも「コードが綺麗」と褒めてくれるようになります.しめしめ.

他にHaskellを書く時に良いツールがあれば是非教えてください.

stylish-haskell

jaspervdj/stylish-haskell: Haskell code prettifier

stack install stylish-haskellでインストール可能です.

stylish-haskellはコード整形ツールです.このツールは

  • importの揃え
  • プラグマの揃え,及び不要なプラグマの削除
  • 無意味な空白の削除
  • レコードの縦揃え
  • パターンマッチの揃え

などをしてくれます.

詳しくは公式サイトを見るのが良いと思います.この記事いる?

この中でもimportの揃えは特異で,単純に行を辞書順に揃えるのではなく,qualifiedが無いimportにもqualified文の空白を入れて,ちゃんとqualifiedを無視したモジュールの辞書順に行を並べてくれます.また,選択importやasパターンも全体的に見て縦に揃うように空白が入ります.

プラグマもソートして適切な空白を入れてくれるため,コードの冒頭部分が格段に見やすくなります.

また「言語拡張をプラグマではなくcabalのdefault-languageでたくさん指定しているから外部のツールが使えない」という人もstylish-haskellなら安心です.stylish-haskell --defaults > .stylish-haskell.yamlでプロジェクトのトップディレクトリに設定ファイルを生成して,言語拡張をyamlのリストに書き込めば使えます.またもちろん,その他の細かい挙動もこのファイルを設定することでいじることが可能です.

コマンドラインでソースを食わせて標準出力にコードを流したり,-iオプションで書き換え一括リファクタリングをすることも可能です.

しかし,コード整形は編集と同時に行ってほしいですよね.もちろん可能です,stylish-haskellは私の調べた限り

の主要テキストエディタと協調して使うことが出来るようです.

特にEmacsは楽でHaskellの編集モードhaskell-modeがサポートしているため,

(custom-set-variables '(haskell-stylish-on-save t))

と設定するだけでセーブ時にstylish-haskellで整形してくれるようになります.

全てのHaskellプログラマにコードを読みやすくするために使って欲しいツールです.切実に使って欲しいです,モジュールのimportが読みにくいことがよくあります.

ただ,stylish-haskellはモジュールの記述部分などは揃えてくれますが,コードの細かい内部にはあまりツッコミを入れてくれません.そういうものが欲しい時は,以下のhlintが使えます.

hlint

ndmitchell/hlint: Haskell source code suggestions

stack install hlintでインストール可能です.

hlintはghcが表示しないような小さな部分の警告をwhy not foobarという形で行ってくれます.

無意味な括弧や無意味なdoを指摘してくれるため,コードがスマートになります.

また,コードの重複している部分を検出して,警告を出すため,適当にコピペして同じような内容の関数が増えるのを防ぐことが可能です.

細かい部分は公式サイトを見たほうが良いと思います.この記事いる?(2回目)

昔は言語拡張にプラグマを使用しない場合は使用不可能でしたが,現在は設定ファイルに言語拡張を書くことが出来るようですね.

例によってVim, Emacs, Atom, VSCodeなどがサポートしていますが,Emacsの場合flycheckを使っていて,hlintがインストールされていれば,自動的にhlintが使用されます.

CIに組み込むことも可能です.私はtravis.ymlに以下のような記述をしています.

install:
  - stack install hlint

script:
  - hlint src

hlintを使用すると無意味な記述を防ぐだけでなく,知らない標準ライブラリの関数を教えてくれるため,初心者Haskellプログラマは少し知識を深めることが可能です.

ただ,すこしうるさいため,私はテストコードにはhlintが警告を出してもある程度は許容しています.本体のコードはデフォルト設定で警告が出ないように気を使ってコードを書いています.