ようこそ。睡眠不足なプログラマのチラ裏です。

Haskellのお勉強 その21

モジュールとは

Haskellで言うモジュールとは、いわゆる関数や型の定義をまとめであり、
Javaで言うところのパッケージであり、.NET(C#,VB)で言うところの
名前空間(namespace)のことと考えて差し支えない。

Haskellのモジュールに属するもの
 ・変数
 ・型コンストラクタ
 ・データコンストラクタ
 ・フィールドラベル
 ・型クラス
 ・クラスメソッド


上記6つをまとめて「エンティティ(entity)」と呼ぶ。
また、Haskellでは.NETと同じようにエンティティに対する名前空間はモジュールごとに分かれており、
別モジュールで同じ名前の関数を定義しても問題ないように設計されている。


基本的なモジュール

Haskellの標準のモジュール

モジュール名 内容
Prelude 言語の基本的な関数、型、型クラスなど
Ratio 有理数
Complex 複素数
Numeric 数値
Ix 値と整数とのマッピング
Array 配列
List リストに関連したユーティリティ
Maybe Maybeモナド
Char 文字に関連したユーティリティ
Monad モナドに関連したユーティリティ
IO 入出力
Directory ディレクトリ(フォルダ)の操作
System コマンドライン引数や環境変数など
Time 日付と時刻
Locale ロケール
CPUTime CPU時間の取得
Random ランダムな数値の取得

なお、すべてのモジュールは、暗黙のうちにPreludeモジュールをインポートされている。
なのでimport宣言を書かなくても、どこでもPreludeモジュールで定義された関数を使うことができる。


階層化ライブラリ

Haskell Hierarchical Libraries
http://www.haskell.org/ghc/docs/latest/html/libraries/index.html



module宣言

新しいモジュールを定義するには、module宣言を使う。

たとえばFileUtilsというモジュールを定義するには、

module FileUtils where

と宣言してモジュールの定義を書くことができる。
モジュールの名前は、アルファベットの大文字で始まる識別子を、「.(ドット)」でつないだ名前となる。
たとえば「Char」「Data.List」「Text.Regex.Lazy」などという具合。
また、上記のようにmodule宣言を書くと、FileUtilsモジュールで定義したエンティティは全てエクスポートされる。
エクスポートされるとはつまり、他のモジュールにインポートして使うことができるということ。



エクスポートするエンティティの限定

特定のエンティティだけをエクスポートするには、次のように書く。

module FileUtils (makePath, forceRemove) where

このように書くと、makePathとforceRemoveだけをエクスポートすることができる。
このエクスポートするエンティティのリストのことを「エクスポートリスト」と言う。
ちなみに、二項演算子をエクスポートする場合は、カッコでくくる必要がある。


こんな具合

module PathUtils (joinPath, (+), concatPath) where


データコンストラクタをエクスポートリストに書きたいときは、
コンストラクタと一緒に書く必要がある。
たとえばSomeTypeという型のデータコンストラクタConsAをエクスポートするには、

module AnyModule (SomeType(ConsA), a, b, c) where


また、複数のデータコンストラクタを指定するときは、
SomeType(ConsA, ConsB)のように書くこともできる。
またある型のすべてのデータコンストラクタとフィールドラベルを一括してエクスポートしたいときは、
SomeType(..)という省略表現で表すことができる。



モジュールのエクスポート

インポートしたモジュールのエンティティを、すべてまとめて再エクスポートするには、
エクスポートリストに「module モジュール名」と書く。


mainモジュール

module宣言を省略すると、ファイルの先頭に次のmodule宣言が暗黙的に設定される。

module Main (main) where

つまり、特に何もmodule宣言をしない場合、
「Mainモジュールの定義を書き、エクスポートリストにmainだけを記述した状態」ということになる。
mainの型は常に、アクション(IO a)でなければならない。