GHCiのコマンド群

GHCiのコマンドは全て「:」ではじまり、一つのコマンド名とそれに続く零個以上のパラメータから成る。コマンド名は短縮することができ、曖昧な場合はより一般的に使われるコマンドが優先される。

:abandon

実行中の評価を捨てる。(ブレークポイントでの停止中のみ有効)

:add [*]module ...

moduleを現在のターゲット集合に追加し、リロードを行う。通常、可能ならそのモジュールのコンパイル済みコードがロードされ、そうでなければそのモジュールはバイトコードにコンパイルされる。接頭辞*を使うことでモジュールがバイトコードとしてロードされることを強制できる。

:back

履歴中を一つ戻る。2.5.5. 追跡と履歴を見よ。:trace:history:forwardも参照。

:break [identifier | [module] line [column]]

指定された関数、または指定された行の指定された位置にブレークポイントを設定する。2.5.1.1. ブレークポイントを設定するを見よ。

:browse[!] [[*]module] ...

moduleで定義されている識別子を表示する。moduleは、GHCiにロードされているか、パッケージの要素でなければならない。moduleが省略された場合、直近にロードされたモジュールが使われる。

*記号がモジュール名の前に置かれたときは、moduleでスコープにある全ての識別子が表示される。そうでない場合、一覧はmoduleがエクスポートしたものに限定される。*形式は解釈実行されているモジュールに対してのみ有効である。コンパイル済みモジュール(パッケージ由来のモジュールも含む)に対しては非*形式の:browseのみが利用可能である。このコマンドの後ろに!記号が置かれた場合、データ構築子とクラスメソッドは個々に表示される。そうでなければ、データ型宣言やクラス宣言の一部としてのみ表示される。!の形式では、さらに、項目をグループに分けて、それぞれについて可能なインポートについてのコメントを付加する。

Prelude> :browse! Data.Maybe
-- not currently imported
Data.Maybe.catMaybes :: [Maybe a] -> [a]
Data.Maybe.fromJust :: Maybe a -> a
Data.Maybe.fromMaybe :: a -> Maybe a -> a
Data.Maybe.isJust :: Maybe a -> Bool
Data.Maybe.isNothing :: Maybe a -> Bool
Data.Maybe.listToMaybe :: [a] -> Maybe a
Data.Maybe.mapMaybe :: (a -> Maybe b) -> [a] -> [b]
Data.Maybe.maybeToList :: Maybe a -> [a]
-- imported via Prelude
Just :: a -> Maybe a
data Maybe a = Nothing | Just a
Nothing :: Maybe a
maybe :: b -> (a -> b) -> Maybe a -> b

この出力が示すのは、現在のセッションの文脈(Preludeのスコープ)で、Data.Maybeの項目の最初の一団がインポートされておらず(ただしGHCiセッションでは完全修飾された形で利用できる。2.4.3. プロンプトで実際にスコープにあるのは何かを見よ)、二番目の一団がPreludeを介してインポートされていて、修飾なし、あるいはPrelude.という修飾子付きの形式で利用できる、ということである。

:cd dir

作業ディレクトリをdirに変更する。dirの先頭が「˜」記号の場合、それはHOME環境変数の内容で置き換えられる。

注意: ディレクトリを変更すると、ロードされているモジュールは全て未ロードになる。これは、探索パスがふつう相対ディレクトリを使って表されており、また、セッションの途中で探索パスを変更することがサポートされていないためである。

:cmd expr

exprIO String型の計算として実行し、その結果の文字列をGHCiコマンドのリストとして実行する。複数のコマンドは改行で区切る。:cmdコマンドは:defおよび:set stopと組み合わせて使うのに便利である。

:continue

ブレークポイントで停止しているとき、実行中の評価を再開する。

:ctags [filename] :etags [filename]

Vi風のエディタ用(:ctags)またはEmacs風エディタ用(:etags)のタグファイルを生成する。ファイル名が指定されなかった場合は、それぞれデフォルトのtagsまたはTAGSが使われる。ロードされているモジュール内の全ての関数、構築子、型のタグが作られる。これらのコマンドが働くには、全てのモジュールが解釈実行されていなければならない。

:def[!] [name expr]

:defは、GHCiにおいて新しいコマンド(マクロと言ってもいい)を定義するのに使われる。コマンド:def name exprは、新しいGHCiコマンド:nameを、Haskellの式exprで実装されたものとして定義する。式の型はString -> IO Stringでなければならない。:name argsがプロンプトに入力されると、GHCiは式(name args)を走らせ、結果のStringを受け取り、それをコマンドの列として再びGHCiに入力する。結果においては、隣り合うコマンドは「\n」で区切られていなければならない。

これは少々ややこしいので、いくつか例を挙げる。まず、次に示す新しいGHCiコマンドは、引数を取らず、結果を生成せず、単に現在の日時を出力するだけのものである。

Prelude> let date _ = Time.getClockTime >>= print >> return ""
Prelude> :def date date
Prelude> :date
Fri Mar 23 15:16:40 GMT 2001

引数を取るコマンドの例を示す。これは:cdの再実装である。

Prelude> let mycd d = Directory.setCurrentDirectory d >> return ""
Prelude> :def mycd mycd
Prelude> :mycd ..

あるいは、現在のディレクトリで「ghc ––make Main」を起動する単純な方法を定義することもできる。

Prelude> :def make (\_ -> return ":! ghc ––make Main")

GHCiへの入力をファイルから読み込むコマンドを定義することもできる。これは、あらかじめ決まった束縛を繰り返しGHCiセッションにロードしたいというときに便利かもしれない。

Prelude> :def . readFile
Prelude> :. cmds.ghci

このコマンドの名前は:.であるが、これは「.」(同じことをするUnixシェルのコマンド)のアナロジーである。

:defと単独で入力すると、現在定義されているマクロの一覧を表示する。既に存在するコマンド名を再定義しようとすると失敗する。ただし:def!の形式が使われた場合は別で、この場合その名前の古いコマンドは黙って失われる。

:delete * | num ...

ブレークポイントを番号で指定して削除する。(それぞれのブレークポイントの番号を見るには:show breaksを使う)。*の形式では、ブレークポイントを全て削除する。

:edit [file]

エディタを開いて、file、それが省略されたときは直近にロードされたモジュールを編集する。起動されるエディタはEDITOR環境変数から採られるか、EDITORが設定されていないときはシステムのデフォルトエディタが使われる。使われるエディタは:set editorで変更することができる。

:etags

:ctagsを見よ。

:force identifier ...

identifierの値を:printと同じ方法で表示する。:printと異なり、:forceは、値をたどっていく間に出会ったサンクを評価する。これによって、例外や無限ループが発生したり、別のブレークポイント(これは無視されるが、その旨表示される)に当ったりするかもしれない。

:forward

履歴中で前進する。2.5.5. 追跡と履歴を見よ。:trace:history:backも参照。

:help , :?

利用可能なコマンドの一覧を表示する。

:

前のコマンドを繰り返す。

:history [num]

評価ステップの履歴を表示する。数値が与えられると、その数のステップを表示する(デフォルト: 20)。:traceと組み合わせて使う。2.5.5. 追跡と履歴を見よ。

:info name ...

与えられた名前についての情報を表示する。例えば、もしnameがクラスなら、クラスメソッドとその型が印字される。もしnameが型構築子なら、その定義が印字される。もしnameが関数なら、その型が印字される。nameがソースファイルからロードされたものであった場合、GHCiはその定義のソースコード中の位置も表示する。

型およびクラスについては、それに言及するインスタンスもまとめて示す。無関係な情報を見せることがないように、インスタンスは、(a)その頭部がnameに言及している、かつ(b)そのインスタンスで言及されているものが全て、:loadまたは:moduleコマンドの結果としてスコープにある(修飾されていてもそうでなくても良い)、場合にのみ表示される。

:kind type

typeの類を推論し、印字する。typeは任意の型式で、Either Intのような型構築子の部分適用であっても構わない。

:load [*]module ...

指定されたmoduleとそれが依存するモジュールすべてを再帰的にロードする。ここで、個々のmoduleはモジュール名またはファイル名でなければならない。また、パッケージ中のモジュールの名前であってはいけない。

以前にロードされていたモジュールは、パッケージ中のものを除いて、忘れ去られる。この新しいモジュールの集合をターゲット集合と呼ぶ。:loadを引数なしで使うと、ロードされているモジュールや束縛を全て未ロードにできることに注意。

通常、可能ならそのモジュールのコンパイル済みコードがロードされ、そうでなければそのモジュールはバイトコードにコンパイルされる。接頭辞*を使うことでモジュールがバイトコードとしてロードされることを強制できる。

:loadコマンドの後、以下のものが文脈として設定される。

  • moduleが成功裡にロードされたなら、module

  • そうでないとき、今回の:loadでロードされたモジュールがあるなら、最後に成功裡にロードされたモジュール。

  • そうでなければ、Prelude

:main arg1 ... argn

プログラムがコンパイルされ実行されるとき、コマンド行引数にアクセスするためにgetArgs関数を使うことができる。しかし、ghciでテストをしているときは、これらの引数を単純にmain関数の引数として渡すことはできない。main関数は直接には引数をとらないからである。

その代わり、:mainコマンドを使うことができる。これは、とにかくスコープにあるmainを、引数がコマンド行から渡されたのと同じようにして実行する。例えば、次のようにである。

Prelude> let main = System.Environment.getArgs >>= print
Prelude> :main foo bar
["foo","bar"]

スペースなどの文字を含む引数は、引用符に入れることができ、Haskellの文字列と同じように扱われる。また、Haskellのリスト構文をそのまま使うこともできる。

Prelude> :main foo "bar baz"
["foo","bar baz"]
Prelude> :main ["foo", "bar baz"]
["foo","bar baz"]

最後に、-main-isフラグや:runコマンドを使えば、その他の関数を呼ぶことができる。

Prelude> let foo = putStrLn "foo" >> System.Environment.getArgs >>= print
Prelude> let bar = putStrLn "bar" >> System.Environment.getArgs >>= print
Prelude> :set -main-is foo
Prelude> :main foo "bar baz"
foo
["foo","bar baz"]
Prelude> :run bar ["foo", "bar baz"]
bar
["foo","bar baz"]
:module [+|-] [*]mod1 ... [*]modn , import mod

プロンプトに入力される文のための文脈を設定または改変する。import modの形式は:module +modと等価である。詳しくは2.4.3. プロンプトで実際にスコープにあるのは何かを見よ。

:print names ...

評価を強制せずに値を表示する。:printは、型が不明、または部分的にしか分かっていない値に対して使うことができる。ブレークポイントにおける、多相型を持った局所変数がこれに当たる。:printは、実行時の値を調査しつつ、その値の型を再構築しようとし、可能ならGHCiの環境中でその型を精密にする。未評価の部分(サンク)に遭遇すると、:printは、それぞれのサンクに対して、_tで始まる名前の新しい変数を束縛する。さらなる情報は2.5.1. ブレークポイントと変数内容の表示を見よ。:sprintコマンドも参照。これは:printと同様だが、新しい変数を束縛しない。

:quit

GHCiを終了する。プロンプトでCtrl-Dを打つことでも終了できる。

:reload

現在のターゲット集合とそれらが依存するモジュールのうち、変更のあったものがあれば、ターゲット集合を再ロードしようと試みる。結果として、新しいモジュールがロードされたり、ターゲットから間接的に必要とされなくなったモジュールが外されたりするかもしれないことに注意せよ。

:run

:mainを見よ。

:set [option...]

色々なオプションを設定する。利用可能なオプションの一覧は2.8. :setコマンドを、GHCi固有のフラグは4.19.10. 対話モードのオプションを見よ。:setコマンド単独では、どのオプションが現在有効になっているか表示する。また、現在の動的フラグの設定状況の一覧も表示する。GHCi固有のフラグは分けて表示される。

:set args arg ...

プログラムがSystem.getArgsを呼んだときに返される引数のリストを設定する。

:set editor cmd

:editコマンドで使われるエディタをcmdにする。

:set prog prog

プログラムがSystem.getProgNameを呼んだときに返される文字列を設定する。

:set prompt prompt

GHCiのプロンプトとして使われる文字列を設定する。promptの中では、%sという並びは現在スコープにあるモジュールの名前に置き換えられ、%%%に置き換えられる。promptが"で始まる場合、HaskellのStringとしてパースされる。そうでない場合はそのまま文字列として扱われる。

:set stop [num] cmd

ブレークポイントに当たったとき、または履歴中で新しい項目が選択されたときに実行されるコマンドを設定する。:set :stopの最も一般的な使われ方は、現在位置のソースコードを表示することである。例えば:set stop :listのようにする。

コマンドの前に数値が与えられた場合、指定されたブレークポイント(だけ)に到達した場合に実行される。これは場合によって非常に便利である。例えば、:set stop 1 :continueとすると、ブレークポイント1に到達した場合必ず:continueが実行されるので、実質的にこのブレークポイントを無効化している。(但し、ブレークポイントに到達した場合のメッセージは出力される)。さらには、:def:cmdを巧妙に使って、:set stopで条件付きブレークポイントを実装することができる。

*Main> :def cond \expr -> return (":cmd if (" ++ expr ++ ") then return \"\" else return \":continue\"")
*Main> :set stop 0 :cond (x < 3)

同様の技法を使えば、指定した回数だけブレークポイントを無視することもできる。

:show bindings

プロンプトで導入された束縛と、その型を表示する。

:show breaks

有効になっているブレークポイントの一覧を表示する。

:show context

ブレークポイントで停止している、継続中の評価の一覧を表示する。

:show modules

現在ロードされているモジュールの一覧を表示する。

:show packages

現在有効なパッケージフラグと、現在ロードされているパッケージの一覧を表示する。

:show languages

現在有効な言語フラグを表示する。

:show [args|prog|prompt|editor|stop]

指定された設定を表示する(:setを見よ)。

:sprint

評価を強制せずに値を表示する。:sprint:printに似ているが、違いは、未評価の部分項が新しい変数に束縛されず、単に「_」と表されることである。

:step [expr]

直近のブレークポイントから一ステップ実行する。引数として式を与えられた場合、その式の評価のステップ実行を開始する。

:trace [expr]

与えられた式を評価(式を与えられなかった場合は直近のブレークポイントから再開)するが、後で:historyで観察できるように評価ステップのログを残す。2.5.5. 追跡と履歴を見よ。

:type expression

expressionの型を推論し、印字する。多相型には明示的な全称量化が加えられる。推論に際して、単相性制限は適用されない。

:undef name

利用者定義のコマンドnameを未定義にする。(上の:defを見よ)

:unset option...

ある種のオプションを無効にする。利用可能なオプションの一覧は、2.8. :setコマンドを見よ。

:! command...

シェルのコマンドcommandを実行する。