2.8. :set:setiコマンド

:setコマンドでは二系統のオプションを設定できる。「+」で始まるGHCiオプションと「-」で始まる「コマンド行」オプションである。

注意: 現在のところ、:setコマンドは引数における引用符の使用を一切サポートしていない。引用符は削除されず、複数の単語を一つにまとめるのに使うこともできない。例えば、:set -DFOO='BAR BAZ'は期待した通りには動かないだろう。

2.8.1. GHCiオプション

GHCiオプションは、:setで有効化、 :unsetで無効化できる。

利用できるGHCiオプションは以下のものである。

+m

複数行コマンドのパースを有効にする。複数行コマンドは、現在の行が閉じていないレイアウト文脈を含んでいる場合に受け付けられる(2.4.3. 複数行入力を見よ)。

+r

通常、ロードされたモジュールにあるトップレベルの式(CAF(Constant Applicative Form)、あるいは定作用形とも呼ばれる)を評価した結果は、複数回のプロンプトでの評価をまたがって保持される。+rを有効にすると、トップレベルの式の評価結果はすべて、一回の評価が終わるごとに捨てられるようになる(それでも一回の評価の間は保持される)。

このオプションは、評価済みのトップレベル式が大量のメモリを消費するときや、再現性のある実行性能の計測をしたいときに有用かもしれない。

+s

一つ式を評価するごとに、経過時間や確保されたバイト数などの統計情報を表示する。注意: 確保されたバイト数はGC毎に計算されるので、これは記憶領域管理器の確保領域の大きさ程度の正確さしかない。そういうわけで、GCが起こらなかった場合、値として0が表示されるかもしれない。

+t

文がプロンプトに入力されたとき、束縛された変数それぞれの型を表示する。入力されたのが単一の式なら、束縛されるのは変数「it」だけである。

2.8.2. GHCiからGHCのコマンド行オプションを設定する

通常のGHCのコマンド行オプションを:setを使って設定することもできる。例えば、-fwarn-missing-signaturesを有効にするには、次のように入力すれば良い。

Prelude> :set -fwarn-missing-signatures

GHCのコマンド行オプションのうち、動的なオプション(4.20. フラグ早見表の表を見よ)として設計されているものは全て、:setを使って有効にすることができる。オプションを無効にするには、逆の効果を持つオプションを有効にすれば良い。

Prelude> :set -fno-warn-incomplete-patterns -XNoMultiParamTypeClasses

4.20. フラグ早見表には、可能なオプション全てについて逆の効果を持つオプションが記されている。

ある種の静的なオプション(特に、-package-I-i-l)も使えるが、次に再ロードするまで効果を発揮しないものもある。

2.8.3. 対話的評価についてのみのオプションを設定する

実際にはGHCiはオプションの集合を二つ保持する。モジュールをロードする際に適用されるものと、プロンプトに式やコマンドが入力されたときに適用されるものである。:setコマンドは両方を変更するが、:seti("set interactive"の略)というコマンドもあって、これは後者にのみ影響する。

この二つのオプションの集合は:set:setiを引数なしで使うことでそれぞれ確認できる。例えば、まっさらなGHCiセッションでは次のようなものを目にするかもしれない。

Prelude> :seti
base language is: Haskell2010
with the following modifiers:
  -XNoMonomorphismRestriction
  -XNoDatatypeContexts
  -XNondecreasingIndentation
  -XExtendedDefaultRules
GHCi-specific dynamic flag settings:
other dynamic, non-language, flag settings:
  -fimplicit-import-qualified
warning settings:

-XExtendedDefaultRulesが有効になっていることに注意。これは、プロンプトに入力された式に特別なデフォルト規則(2.4.8. GHCiにおける型のデフォルト化を見よ)を適用しているからである。

加えて、GHCiでは単相性限定はデフォルトで無効になっている。(7.13.9.1. 恐怖の単相性限定を無効にするを見よ)。

プロンプトに入力される式についてのみ言語オプションを変え、ロードされるモジュールにはそのオプションを適用しないでおくのが便利なことがよくある。例えば、

:seti -XMonoLocalBinds

-XMonoLocalBindsがロードされるモジュールにも適用されるのは望ましくないだろう。コンパイルエラーを引き起すかもしれないが、もっとよくあるのは、フラグが変わったのでモジュールの再コンパイルが必要だとGHCが判断することで、無駄な再コンパイルが発生することである。

従って、.ghciファイルで言語オプションを設定するときは、本当にGHCiにロードするモジュール全てにそれを適用したいのでない限り、:setでなく:setiを使うのが良い習慣である。