Haskellの階層的モジュール

http://www.kotha.net/ghcguide_ja/latest/syntax-extns.html#hierarchical-modules に,

GHCは、モジュール名の構文について、ある小さな拡張をサポートしている。すなわち、モジュール名はドット「.」を含むことができる。これは「階層的モジュール名前空間」拡張とも呼ばれる。これは、通常平坦な Haskellモジュールの名前空間を拡張して、より柔軟な、モジュールの階層をつくり出すからである。

ってあったので,Hugsならどうなるの,と思ったのが始まり.

また,http://www.kotha.net/ghcguide_ja/latest/separate-compilation.html に,

ふつう、ファイル名は、モジュール名をもとにして、ドットをディレクトリ区切りに置き換えたものにされるべきである。例えば、 Unixシステムでは、A.B.Cというモジュールは、なんらかの基底ディレクトリからの相対パスでA/B/C.hsというファイルに置かれるべきである。他のモジュールからインポートされる予定がないモジュールには(例えばMain)、どんな名前をつけても構わない。

ってあるが,「ふつう〜であるべきである.」って書いてあるので,強制なのかどっちやねん,と思ったのも始まり.

結果として全ての環境で,A.B.Cというモジュールを作った場合は,A/B/C.hsというファイル構成にしなければコンパイルエラーが出た.

実験

GHC,GHCi,Hugsでそれぞれ実験.

  • Main.hs
import A.B.C

main = print c
  • C.hs
module A.B.C where

c = 3
ファイル構成
  • テスト1
    • test1/Main.hs
    • test1/A/B/C.hs
  • テスト2
    • test1/Main.hs
    • test1/C.hs
テスト1の環境でコンパイル

全て成功.しかし,GHCは--makeをオプション指定しなければ失敗した.

$ ghc --make Main.hs
Linking Main ...
$ ./Main 
3
  • GHCi
Prelude> :l Main.hs
Ok, modules loaded: A.B.C, Main.
Prelude Main> :main
3
Main> :l Main.hs
Main> :main
3
テスト2の環境でコンパイル

全て失敗した.

$ ghc --make Main.hs

Main.hs:1:7:
    Could not find module `A.B.C':
      Use -v to see a list of the files searched for.
  • GHCi
Prelude> :l Main.hs 

Main.hs:1:7:
    Could not find module `A.B.C':
      Use -v to see a list of the files searched for.
Failed, modules loaded: none.
Hugs> :l Main.hs 
ERROR "Main.hs" - Can't find imported module "A.B.C"