インデントで悩まないための単純な指針
Haskellコードを書いていて、インデントを揃えるのが面倒だとか、インデントが揃っているか判別しにくいということがあるかもしれない。以前は私にもよくあったのだが、二つの簡単な指針に従うことに決めてからこの種の問題に悩まされることはなくなった。ので紹介する。
- インデントを揃える際は、そこより左には空白しか置かない
- インデントは常にkの倍数個の半角スペースで行う。ここでkはプロジェクトごとの定数(以下ではk=2)
具体例
foo x y = do runThis runThat
と書かずに、
foo x y = do runThis runThat
と書く。
foo = bar * 2 where bar = 1 + quux quux = log 3
と書かずに、
foo = bar * 2 where bar = 1 + quux quux = log 3
と書く。
data Foo a = Foo { fooId :: !Int , fooName :: !String , fooRef :: !(IORef a) }
と書かずに、
data Foo a = Foo { fooId :: !Int , fooName :: !String , fooRef :: !(IORef a) }
と書く。
build = runBuilder $ fromInt foo <> fromInt bar <> fromString baz
と書かずに、
build = runBuilder $ fromInt foo <> fromInt bar <> fromString baz
と書く。
何が良いか
行頭にスペース以外を置かないので、
- 識別子の名前変更や、引数の追加/削除によってインデントを変更する必要がない
- ほとんど必要最小限のインデント量になるので、コードが無駄に横に長くなりにくい。whereの三段ネストくらいなら平気でできる*1
- Unicodeの記号を使ってもずれない。プロポーショナルフォントですら問題ない
常にkの倍数個のスペースでインデントするので、
- インデント水準の変更が簡単*2
- 異なるインデント水準は最低でもk桁違うので見分けやすい
何が悪いか
doの中でletを使うときに微妙に格好悪い。
do let foo = 1 bar = 2 go foo bar
以下のように書きたくなる。(とくにk=4の場合)
do let foo = 1 bar = 2 go foo bar
また、人によってはwhere節の内部がインデントされすぎると感じる。原則を曲げてwhereをk/2だけインデントする方が好きな人もいるかもしれない。
foo = bar * 2 where bar = 1 + quux quux = log 3