Midoliy |> F# - 名前空間
名前空間
Midoliy|F#プログラミング
名前空間とは
入れ子の名前空間

名前空間とは


   名前空間(= namespace)とは、関連する機能を名前をつけてグループ化したもののことを指します。名前空間を使う場合は、F#ファイルの中で最上位の要素として宣言しなければなりません。 基本的には名前空間よりも上の行には コンパイラディレクティブ しか書くことができません。
 また、名前空間の中には直接 "値" や "関数" などを含めることができないので、moduletype などを宣言し、それらに必要な値や関数を定義しなければなりません。
 module や type については別の章で解説するので、今回は「そんなのもあるんだ~」ぐらいでサラッと流してください。
// 計算する機能を集めたグループを作成
// 最上位の要素
namespace Calc

// 名前空間の中には直接関数を定義できないため、moduleを宣言します
module MyCalc =
    // 足し算
    let plus x y = x + y

    // 引き算
    let sub x y = x - y

    // 掛け算
    let mul x y = x * y

    // 割り算
    let div x y = x / y

 以下のように、1つのファイルに複数の名前空間を定義することも可能です。
// 1つ目の名前空間
namespace Hoge      // ここから下が Hoge名前空間となります

// Hoge名前空間 の中の MyHogeモジュール
module MyHoge =
    // Hoge名前空間 の中の MyHogeモジュール の中の f関数
    let f x y = x + y


// 2つ目の名前空間
namespace Fuga      // ここから下が Fuga名前空間となります(1行前までがHoge名前空間)

// Fuga名前空間 の中の MyFugaモジュール
module MyFuga =
    // Fuga名前空間 の中の MyFugaモジュール の中の f関数
    let f x y = x + y

 名前空間(またはモジュール名)が異なっていれば、sample2.fs の f関数 のように同じ名前で同じ引数の関数を定義することも可能です。
 利用する場合は以下のように記述して区別します。
// Hoge名前空間 の中の MyHogeモジュール の中の f関数 を利用
let answer1 = Hoge.MyHoge.f 10 20

// Fuga名前空間 の中の MyFugaモジュール の中の f関数 を利用
let answer2 = Fuga.MyFuga.f 10 20

 このように、
名前空間.モジュール名.関数名
名前空間.モジュール名.値名

などと記述することで、関数や値にアクセスすることができます。

 また、下記のように、モジュール宣言のあとに名前空間を定義することはできないので、注意してください。
module MyHoge =
    // MyHogeモジュール の中の f関数
    let f x y = x + y


// モジュール宣言のあとに名前空間を宣言することはできません.
// 以下はエラーとなります.
// namespace Fuga       

// Fuga名前空間 の中の MyFugaモジュール
module MyFuga =
    // Fuga名前空間 の中の MyFugaモジュール の中の f関数
    let f x y = x + y// ファイルの先頭に モジュール宣言 をするときは = を書いてはいけません
    module MyHoge 
        // MyHogeモジュール の中の f関数
        let f x y = x + y
    
    
    // モジュール宣言のあとに名前空間
    // このような書き方はエラー
    namespace Fuga       
    
    // Fuga名前空間 の中の MyFugaモジュール
    module MyFuga =
        // Fuga名前空間 の中の MyFugaモジュール の中の f関数
        let f x y = x + y


入れ子の名前空間


 名前空間の中に名前空間を定義するような、入れ子になっている名前空間を定義することもできます。.NETの名前空間を "入れ子の名前空間" のサンプルとして紹介します。
 ※ サンプルのモジュール名やクラス名は架空のものです。。
namespace System
//  System名前空間 の中に Integerクラス を定義
type Integer (i:int) =
    let Value = i

// System名前空間 の中の IO名前空間 (= 入れ子になった名前空間)
namespace System.IO

// System.IO名前空間 の中に Fileモジュール を定義
module File =
    let Exist filename = true   // とりあえずtrue返すだけ