次のようなHaskellソースコードがMain.hs
というファイルに置かれているとしよう。
main = print (fac 20) fac 0 = 1 fac n = n * fac (n-1)
Main.hs
はどこでも好きなところに保存することができるが、カレントディレクトリ[3]以外の場所に保存した場合、GHCiでディレクトリを正しく変更する必要がある。
Prelude> :cd dir
ここで、dir
はMain.hs
を保存したディレクトリ(あるいはフォルダ)である。
HaskellのソースファイルをGHCiにロードするには、:load
コマンドを使う。
Prelude> :load Main Compiling Main ( Main.hs, interpreted ) Ok, modules loaded: Main. *Main>
GHCiはMain
モジュールをロードし、プロンプトが「*Main>
」に変わった。これは、プロンプトに入力される式を評価するのに使われる文脈が、今ロードしたばかりのMain
モジュールになったことを示すためのものである(*
が何を意味するかについては2.4.5. プロンプトで実際にスコープにあるのは何かで説明する)。つまり、これでMain.hs
で定義された関数を含む式を入力できるようになったということである。
*Main> fac 17 355687428096000
複数のモジュールからなるプログラムをロードするのも同様に簡単である。「最上位の」モジュールの名前を:load
コマンドに指定すれば良い(ヒント: :load
は:l
に短縮できる)。最上位のモジュールはふつうMain
であるが、必ずしもそうである必要はない。GHCiは最上位のモジュールから直接・間接に必要とされているモジュールを見付け、それらを依存関係の順にロードする。
GHCはM
というモジュールがどのファイルにあるかをどのようにして知るのだろうか。GHCiは、
またはM
.hs
というファイルを探すのである。したがって、大部分のモジュールでは、モジュール名とファイル名は一致しなければならない。一致しなかった場合、GHCiはモジュールを見つけ出すことができない。M
.lhs
この規則には一つの例外がある。:load
を使ってプログラムをロードするとき、あるいはghci
を起動するとき、モジュール名ではなくファイル名を指定することができる。そのファイルはもし存在するならロードされ、どんなモジュールを含んでいても構わない。これは、複数のMain
モジュールが一つのディレクトリにある場合、全てをMain.hs
と呼ぶことはできないので、特に便利である。
ソースファイルを探すときの探索パスは、次に示すように、GHCiのコマンド行で-i
を使って指定することができる。
ghci -idir1
:...:dirn
あるいは、GHCiの中から:set
コマンドを使って設定することもできる(2.8.2. GHCiからGHCのコマンド行オプションを設定するを見よ)[4]。
GHCiが上記のような方法で依存関係を追うことの帰結として、全てのモジュールにソースファイルがなければならない、というものがある。唯一の例外はパッケージ由来のモジュールで、これにはPrelude
や、IO
、Complex
といった標準ライブラリも含まれる。モジュールをロードしようとたときGHCiがソースファイルを見付けられなかった場合、たとえそのモジュールのオブジェクトファイルやインタフェースファイルがあったとしても、エラーメッセージが表示されるだろう。
ソースコードに変更を加えて、GHCiに再コンパイルさせたいときは、:reload
コマンドを使えば良い。プログラムは必要に応じて再コンパイルされる。このとき、GHCiは依存関係の変化がないモジュールを実際に再コンパイルするのを避けようと最善を尽くす。これは一括コンパイル時に再コンパイルを避ける機構(4.7.8. 再コンパイル検査器を見よ)と同じである。
GHCiをシェルから起動したのなら、GHCiのカレントディレクトリはシェルのそれと同じである。GHCiをWindowsの「スタート」メニューから起動したなら、カレントディレクトリはおそらくC:\Documents and Settings\
あたりになる。user name
GHCiや--make
モードでは-i
オプションはソースファイルの探索パスを指定するのに対し、標準の一括コンパイルモードでは-i
オプションはインターフェースファイルの探索パスを指定することに注意。4.7.3. 探索パスを見よ。