モジュール (F#)

F# 言語のコンテキストで モジュールとは、プログラム内に含まれる値、型、関数値などのコードのグループです。モジュールでコードをグループ化すると、関連するコードをまとめることができ、プログラム内で名前の競合を回避するのに役立ちます。

// Top-level module declaration. 
module [accessibility-modifier] [qualified-namespace.]module-name
declarations
// Local module declaration.
module [accessibility-modifier] module-name =
   declarations

解説

F# でのモジュールとは、型、値、関数値、do 束縛のコードなどのコード コンストラクターのグループです。モジュールは、静的メンバーのみを持つ共通言語ランタイム (CLR: Common Language Runtime) クラスとして実装されます。モジュール宣言には、ファイル全体がモジュール内に含まれるかどうかに応じて、最上位モジュール宣言とローカル モジュール宣言の 2 種類があります。最上位モジュール宣言を使用すると、ファイル全体がモジュールに含まれます。最上位モジュール宣言を記述できるのは、ファイル内の最初の宣言だけです。

最上位モジュール宣言の構文における qualified-namespace オプションは、モジュールを含む入れ子の名前空間名のシーケンスで指定します。修飾名前空間は、以前に宣言されたものである必要はありません。

最上位モジュールの宣言をインデントする必要はありません。ローカル モジュールの場合は、すべての宣言をインデントする必要があります。ローカル モジュール宣言では、そのモジュール宣言の下のインデントされた宣言だけがモジュールに含まれます。

コード ファイルの先頭が最上位モジュール宣言でも名前空間宣言でもはない場合は、すべてのローカル モジュールを含むファイルの内容全体が、暗黙で作成された最上位モジュールに含まれます。この最上位モジュールの名前はこのファイル名と同じですが、拡張子がなく、先頭は大文字になっています。たとえば、次のようなファイルがあるとします。

// In the file program.fs.
let x = 40

このファイルは、次のように記述されている場合と同じ方法でコンパイルされます。

module Program
let x = 40

1 つのファイルで複数のモジュールを使用する場合は、各モジュールに対してローカル モジュール宣言を使用する必要があります。外側の名前空間が宣言されている場合、これらのモジュールは外側の名前空間に含まれます。外側の名前空間が宣言されていない場合、これらのモジュールは暗黙で作成された最上位モジュールに含まれます。複数のモジュールを含むコード ファイルのコード例を次に示します。Multiplemodules という名前の最上位モジュールがコンパイラによって暗黙で作成され、MyModule1 と MyModule2 がその最上位モジュールの入れ子になります。

// In the file multiplemodules.fs.
// MyModule1
module MyModule1 =
    // Indent all program elements within modules that are declared with an equal sign.
    let module1Value = 100

    let module1Function x =
        x + 10

// MyModule2
module MyModule2 =

    let module2Value = 121

    // Use a qualified name to access the function.
    // from MyModule1.
    let module2Function x =
        x * (MyModule1.module1Function module2Value)

1 つのプロジェクトまたはコンパイルに複数のファイルが含まれる場合、またはライブラリを構築する場合は、ファイルの先頭で名前空間またはモジュールを宣言する必要があります。F# コンパイラは、プロジェクトまたはコンパイル コマンド ラインに含まれるファイルが 1 つのみであり、かつアプリケーションを作成する場合に限り、モジュール名を暗黙的に決定します。

accessibility-modifier には、public、private、internal のいずれかを指定できます。詳細については、「アクセス制御 (F#)」を参照してください。既定値は public です。

モジュール内のコードの参照

別のモジュールの関数、型、および値を参照する場合は、修飾名を使用するか、モジュールを開く必要があります。修飾名を使用する場合は、対象のプログラム要素の名前空間、モジュール、および識別子を指定する必要があります。修飾パスの各要素は、次のようにドット (.) で区切ります。

Namespace1.Namespace2.ModuleName.Identifier

モジュールまたは 1 つ以上の名前空間を開くと、コードを簡素化できます。名前空間およびモジュールを開く方法の詳細については、「インポート宣言: open キーワード (F#)」を参照してください。

ファイルの末尾までのすべてのコードを含む最上位モジュールのコード例を次に示します。

module Arithmetic

let add x y =
    x + y

let sub x y =
    x - y

同一プロジェクト内の別のファイルからこのコードを使用するには、次の例に示すように、修飾名を使用します。または、関数を使用する前にモジュールを開きます。

// Fully qualify the function name.
let result1 = Arithmetic.add 5 9
// Open the module.
open Arithmetic
let result2 = add 5 9

入れ子になったモジュール

モジュールは入れ子構造にできます。新しいモジュールではなく、内側のモジュールであることを示すためには、内側のモジュールのインデントを外側のモジュールの宣言よりも下げる必要があります。たとえば、次の 2 つの例を比較します。次のコードの Z モジュールは内側のモジュールです。

module Y =
    let x = 1 

    module Z =
        let z = 5

ただし、次のコードでは、Z モジュールが Y モジュールの兄弟になります。

module Y =
    let x = 1 

module Z =
    let z = 5

次のコードの Z モジュールも兄弟モジュールになります。このモジュールのインデントが、Y モジュールのその他の宣言よりも下げられていないためです。

module Y =
        let x = 1

    module Z =
        let z = 5

最後に、外側のモジュールでは何も宣言されておらず、その直後に別のモジュールが宣言されている場合は、その新しく宣言されたモジュールが内側のモジュールと見なされます。ただし、2 つ目のモジュール定義のインデントが 1 つ目のモジュール定義よりも下げられていない場合は、コンパイラによって警告が生成されます。

// This code produces a warning, but treats Z as a inner module.
module Y =
module Z =
    let z = 5

警告が生成されないようにするには、内側のモジュールをインデントします。

module Y =
    module Z =
        let z = 5

ファイル内のすべてのコードを単一の外側のモジュールに含める必要があり、内側のモジュールも必要な場合は、外側のモジュールに等号を付ける必要はありません。また、外側のモジュールの範囲内の宣言 (内側のモジュール宣言を含む) をインデントする必要もありません。内側のモジュール宣言の内部の宣言については、インデントする必要があります。この場合のコードを次に示します。

// The top-level module declaration can be omitted if the file is named
// TopLevel.fs or topLevel.fs, and the file is the only file in an
// application.
module TopLevel

let topLevelX = 5

module Inner1 =
    let inner1X = 1
module Inner2 =
    let inner2X = 5

参照

関連項目

名前空間 (F#)

その他の技術情報

F# 言語リファレンス