はじめに

つい最近 haskell-jp で 皆さんPreludeは何を使っていますか? という話がありました。

まとめるとだいたこんな感じです。

カスタム Prelude パッケージ 利用しているプロジェクト
base-prelude ???
classy-prelude Yesod
protolude purescript
universum cardano-sl
rio stack

カスタム Prelude を使うモチベーションは、自分のよく使う関数を Prelude に入れたいとか、fromJust みたいな部分関数を排除したいなど、色々あります。

実際にカスタム Prelude を使うためにはファイルの先頭に NoImplicitPrelude 言語拡張とカスタムPreludeの import 宣言を追加する必要があります。(具体例として rio パッケージを利用します)

新しいファイルを作るたびに、ファイルの先頭に上記の宣言を書いても良いのですが、今回はこの作業なしにカスタム Prelude を使う方法をご紹介したいと思います。

default-extensions を利用する

{-# LANGUAGE NoImplicitPrelude #-} を自動的に有効化させることは意外と簡単です。

package.yamlcabal ファイルの default-extensions に追加するだけです。

# project.cabal
default-extensions: NoImplicitPrelude

この場合、全てのファイルで自動的に NoImplicitPrelude が有効になるため、カスタム Prelude の import 宣言のみが必要となります。

まだ import RIO が残っているので、こいつをなんとかしましょう。

base-noprelude パッケージ

Add -prelude-is flag というチケットで紹介されている方法を使えば、import RIO を記述することなく、Prelude のように利用できるようになります。

このチケットによれば -prelude-is というオプションを導入しようとしていたようですが、そんなことしなくても Prelude を置き換えれるよ!という話です。

具体的には base-noprelude パッケージを利用します。

最小構成

この方法もかなり簡単で、stack.yaml, package.yaml, src/Prelude.hs をちょこっと書くだけで完成です。

確認

ファイルに import RIO を書かなくても本当に良いのか確かめてみます。

当然、通常の Prelude には Texttshow も無いので、import RIO が有効になっていなければ、ビルドエラーになるはずです。

ghci で確認してみましょう。

ちゃんと動いてそうですね。

まとめ

実際にこの手法で開発を進めているわけではないので、もしかすると落とし穴があるかもしれませんが、思ったより使いやすくてびっくりしました。

元の Prelude に戻すことも簡単だと思うので、興味があれば試してみて下さい。(結構前のチケットなので、周知の事実だったらすみません・・・。)