Haskell でのモジュール import

date:2012/11/09

1. 概要

  1. 基本的には、名前空間を分けずにimportされる。
  2. 特定の関数をimportする場合は、タプルで指定。
  3. 特定の関数以外を使いたい(名前が衝突してるとか、自前実装した、とか)場合は、hiding でタプル指定。
  4. 名前空間を完全に分けたい場合は、qualified をつける。
  5. 別の名前をつけるには、as を使う。その場合、元々の名前は使えない。

2. いくつかの import の方法

以下にいくつかのパターンを書いてみます。
()内は、x を関数とした時の、x の呼び出し例です。
  1. 普通のインポート(x, Data.List.x)
import Data.List
  1. Data.List の nub だけをインポート(x, Data.List.x)
import Data.List (nub)
  1. Prelude の zip 以外をimport(x, Data.List.x)
import Data.List hiding (nub)
  1. 名前空間を限定(Data.List.x)
import qualified Data.List
  1. 別の名前をつける(M.x)
import qualified Data.List as M
そういうわけで、import には、qualified をつけた方が良い気がします。
デフォルトで名前空間を分けるような関数が欲しいです。

3. 注意

先ほどのように、importはデフォルトで名前空間を分けずに、importしようとします。
一方で、 Haskell は同じ関数を複数宣言することができません。(一度宣言した関数を変更できないという話だったはず)
では、次のコードでエラーになるでしょうか? Prelude には 普通の意味の (==) が宣言されています。
import Prelude

(==) :: Bool -> Bool -> Bool
True == _ = True
False == x = x

main = do
   -- 何か複雑な処理
Answer:エラーになりません
たぶん理由は、名前空間が分割されているから。
関数呼び出しには、(Main.==) や (Prelude.==) としないと、”Ambiguous occurrence” で怒られます。

4. まとめ

そういうわけで、Haskell の import がわかったことになった。
qualified を積極的に使いましょう。