F Sharp Programming/Modules and Namespaces

Modules and Namespaces are primarily used for grouping and organizing code.
Defining Modules.
No code is required to define a module. If a codefile does not contain a leading codice_1 or codice_2 declaration, F# code will implicitly place the code in a module, where the name of the module is the same as the file name with the first letter capitalized.
To access code in another module, simply use codice_3 notation: codice_4. Notice that this notation is similar to the syntax used to access static members—this is not a coincidence. F# modules are compiled as classes which only contain static members, values, and type definitions.
Let's create two files:
DataStructures.fs
type 'a Stack =
 | EmptyStack
 | StackNode of 'a * 'a Stack
let rec getRange startNum endNum =
 if startNum &gt; endNum then EmptyStack
 else StackNode(startNum, getRange (startNum+1) endNum)
Program.fs
let x =
 DataStructures.StackNode(1,
 DataStructures.StackNode(2,
 DataStructures.StackNode(3, DataStructures.EmptyStack)))
let y = DataStructures.getRange 5 10
printfn "%A" x
printfn "%A" y
This program outputs:
Like all modules, we can use the codice_7 keyword to give us access to the methods inside a module without fully qualifying the naming of the method. This allows us to revise codice_6 as follows:
open DataStructures
let x = StackNode(1, StackNode(2, StackNode(3, EmptyStack)))
let y = getRange 5 10
printfn "%A" x
printfn "%A" y
Submodules.
Its very easy to create submodules using the codice_2 keyword:
type 'a Stack =
 | EmptyStack
 | StackNode of 'a * 'a Stack
module StackOps =
 let rec getRange startNum endNum =
 if startNum &gt; endNum then EmptyStack
 else StackNode(startNum, getRange (startNum+1) endNum)
Since the codice_10 method is under another module, the fully qualified name of this method is codice_11. We can use it as follows:
open DataStructures
let x =
 StackNode(1, StackNode(2, StackNode(3, EmptyStack)))
let y = StackOps.getRange 5 10
printfn "%A" x
printfn "%A" y
F# allows us to create a module and a type having the same name, for example the following code is perfectly acceptable:
type 'a Stack =
 | EmptyStack
 | StackNode of 'a * 'a Stack
module Stack =
 let rec getRange startNum endNum =
 if startNum &gt; endNum then EmptyStack
 else StackNode(startNum, getRange (startNum+1) endNum)
Extending Types and Modules.
F# supports extension methods, which allow programmers to add new static and instance methods to classes and modules without inheriting from them.
Extending a Module
The codice_12 module contains several pairs of methods:
codice_12 has a codice_18 member, but does not have a corresponding codice_19 function, which includes the index of each sequence element. We add this missing method to the module simply by creating another module with the same name. For example, using fsi:
&gt; module Seq =
 let foralli f s =
 s
 |&gt; Seq.mapi (fun i x -&gt; i, x) (* pair item with its index *)
 |&gt; Seq.forall (fun (i, x) -&gt; f i x) (* apply item and index to function *)
let isPalindrome (input : string) =
 input
 |&gt; Seq.take (input.Length / 2)
 |&gt; Seq.foralli (fun i x -&gt; x = input.[input.Length - i - 1]);;
module Seq = begin
 val foralli : (int -&gt; 'a -&gt; bool) -&gt; seq&lt;'a&gt; -&gt; bool
end
val isPalindrome : string -&gt; bool
&gt; isPalindrome "hello";;
val it : bool = false
&gt; isPalindrome "racecar";;
val it : bool = true
Extending a Type
The codice_20 has many useful methods, but let's say we thought it was missing a few important functions, codice_21 and codice_22. Since this class is marked as codice_23 or codice_24, we can't create a derived version of this class. Instead, we create a module with the new methods we want. Here's an example in fsi which demonstrates how to add new static and instance methods to the codice_25 class:
&gt; module Seq =
 let foralli f s =
 s
 |&gt; Seq.mapi (fun i x -&gt; i, x) (* pair item with its index *)
 |&gt; Seq.forall (fun (i, x) -&gt; f i x) (* apply item and index to function *)
module StringExtensions =
 type System.String with 
 member this.IsPalindrome =
 this
 |&gt; Seq.take (this.Length / 2)
 |&gt; Seq.foralli (fun i x -&gt; this.[this.Length - i - 1] = x)
 static member Reverse(s : string) =
 let chars : char array =
 let temp = Array.zeroCreate s.Length
 let charsToTake = if temp.Length % 2 &lt;&gt; 0 then (temp.Length + 1) / 2 else temp.Length / 2
 s
 |&gt; Seq.take charsToTake
 |&gt; Seq.iteri (fun i x -&gt;
 temp.[i] &lt;- s.[temp.Length - i - 1]
 temp.[temp.Length - i - 1] &lt;- x)
 temp
 new System.String(chars)
open StringExtensions;;
module Seq = begin
 val foralli : (int -&gt; 'a -&gt; bool) -&gt; seq&lt;'a&gt; -&gt; bool
end
module StringExtensions = begin
end
&gt; "hello world".IsPalindrome;;
val it : bool = false
&gt; System.String.Reverse("hello world");;
val it : System.String = "dlrow olleh"
Module Signatures.
By default, all members in a module are accessible from outside the module. However, a module often contain members which should not be accessible outside itself, such as helper functions. One way to expose only a subset of a module's members is by creating a signature file for that module. (Another way is to apply .Net CLR access modifiers of public, internal, or private to individual declarations).
Signature files have the same name as their corresponding module, but end with a ".fsi" extension (f-sharp interface). Signature files always come before their implementation files, which have a corresponding ".fs" extension. For example:
DataStructures.fsi
type 'a stack =
 | EmptyStack
 | StackNode of 'a * 'a stack
module Stack =
 val getRange : int -&gt; int -&gt; int stack
 val hd : 'a stack -&gt; 'a
 val tl : 'a stack -&gt; 'a stack
 val fold : ('a -&gt; 'b -&gt; 'a) -&gt; 'a -&gt; 'b stack -&gt; 'a
 val reduce : ('a -&gt; 'a -&gt; 'a) -&gt; 'a stack -&gt; 'a
DataStructures.fs
type 'a stack =
 | EmptyStack
 | StackNode of 'a * 'a stack
module Stack =
 (* helper functions *)
 let internal_head_tail = function
 | EmptyStack -&gt; failwith "Empty stack"
 | StackNode(hd, tail) -&gt; hd, tail
 let rec internal_fold_left f acc = function
 | EmptyStack -&gt; acc
 | StackNode(hd, tail) -&gt; internal_fold_left f (f acc hd) tail
 (* public functions *)
 let rec getRange startNum endNum =
 if startNum &gt; endNum then EmptyStack
 else StackNode(startNum, getRange (startNum+1) endNum)
 let hd s = internal_head_tail s |&gt; fst
 let tl s = internal_head_tail s |&gt; snd
 let fold f seed stack = internal_fold_left f seed stack
 let reduce f stack = internal_fold_left f (hd stack) (tl stack)
Program.fs
open DataStructures
let x = Stack.getRange 1 10
printfn "%A" (Stack.hd x)
printfn "%A" (Stack.tl x)
printfn "%A" (Stack.fold ( * ) 1 x)
printfn "%A" (Stack.reduce ( + ) x)
Since codice_26 is not defined in our interface file, the method is marked codice_27 and no longer accessible outside of the codice_28 module.
Module signatures are useful to building a code library's skeleton, however they have a few caveats. If you want to expose a class, record, or union in a module through a signature, then the signature file must expose "all" of the objects members, records fields, and union's cases. Additionally, the signature of the function defined in the module and it's corresponding signature in the signature file must match "exactly". Unlike OCaml, F# does not allow a function in a module with the generic type codice_29 to be restricted to codice_30 in the signature file.
Defining Namespaces.
A namespace is a hierarchical categorization of modules, classes, and other namespaces. For example, the codice_31 namespace groups together all of the collections and data structures in the .NET BCL, whereas the codice_32 namespace groups together all classes which provide cryptographic services.
Namespaces are primarily used to avoid name conflicts. For example, let's say we were writing an application incorporated code from several different vendors. If Vendor A and Vendor B both have a class called codice_33, and we wrote the code codice_34, how would the compiler know whether which stack we intended to create? Namespaces can eliminate this ambiguity by adding one more layer of grouping to our code.
Code is grouped under a namespace using the codice_1 keyword:
DataStructures.fsi
namespace Princess.Collections
 type 'a stack =
 | EmptyStack
 | StackNode of 'a * 'a stack
 module Stack =
 val getRange : int -&gt; int -&gt; int stack
 val hd : 'a stack -&gt; 'a
 val tl : 'a stack -&gt; 'a stack
 val fold : ('a -&gt; 'b -&gt; 'a) -&gt; 'a -&gt; 'b stack -&gt; 'a
 val reduce : ('a -&gt; 'a -&gt; 'a) -&gt; 'a stack -&gt; 'a
DataStructures.fs
namespace Princess.Collections
 type 'a stack =
 | EmptyStack
 | StackNode of 'a * 'a stack
 module Stack =
 (* helper functions *)
 let internal_head_tail = function
 | EmptyStack -&gt; failwith "Empty stack"
 | StackNode(hd, tail) -&gt; hd, tail
 let rec internal_fold_left f acc = function
 | EmptyStack -&gt; acc
 | StackNode(hd, tail) -&gt; internal_fold_left f (f acc hd) tail
 (* public functions *)
 let rec getRange startNum endNum =
 if startNum &gt; endNum then EmptyStack
 else StackNode(startNum, getRange (startNum+1) endNum)
 let hd s = internal_head_tail s |&gt; fst
 let tl s = internal_head_tail s |&gt; snd
 let fold f seed stack = internal_fold_left f seed stack
 let reduce f stack = internal_fold_left f (hd stack) (tl stack)
Program.fs
open Princess.Collections
let x = Stack.getRange 1 10
printfn "%A" (Stack.hd x)
printfn "%A" (Stack.tl x)
printfn "%A" (Stack.fold ( * ) 1 x)
printfn "%A" (Stack.reduce ( + ) x)
Where is the codice_28 Module?
You may have expected the code in codice_6 above to open codice_38 rather than codice_39. According to the F# spec, F# treats "anonymous implementation files" (which are files without a leading codice_2 or codice_1 declaration) by putting all code in an implicit module which matches the code's filename. Since we have a leading codice_1 declaration, F# does not create the implicit module.
.NET does not permit users to create functions or values outside of classes or modules. As a consequence, we cannot write the following code:
namespace Princess.Collections
 type 'a stack =
 | EmptyStack
 | StackNode of 'a * 'a stack
 let somefunction() = 12 (* &lt;--- functions not allowed outside modules *)
If we prefer to have a module called codice_28, we can write this:
namespace Princess.Collections
 module DataStructures
 type 'a stack =
 | EmptyStack
 | StackNode of 'a * 'a stack
 let somefunction() = 12
Or equivalently, we define a module and place it a namespace simultaneously using:
module Princess.Collections.DataStructures
 type 'a stack =
 | EmptyStack
 | StackNode of 'a * 'a stack
 let somefunction() = 12
Adding to Namespace from Multiple Files.
Unlike modules and classes, any file can contribute to a namespace. For example:
DataStructures.fs
namespace Princess.Collections
 type 'a stack =
 | EmptyStack
 | StackNode of 'a * 'a stack
 module Stack =
 (* helper functions *)
 let internal_head_tail = function
 | EmptyStack -&gt; failwith "Empty stack"
 | StackNode(hd, tail) -&gt; hd, tail
 let rec internal_fold_left f acc = function
 | EmptyStack -&gt; acc
 | StackNode(hd, tail) -&gt; internal_fold_left f (f acc hd) tail
 (* public functions *)
 let rec getRange startNum endNum =
 if startNum &gt; endNum then EmptyStack
 else StackNode(startNum, getRange (startNum+1) endNum)
 let hd s = internal_head_tail s |&gt; fst
 let tl s = internal_head_tail s |&gt; snd
 let fold f seed stack = internal_fold_left f seed stack
 let reduce f stack = internal_fold_left f (hd stack) (tl stack)
MoreDataStructures.fs
namespace Princess.Collections
 type 'a tree when 'a :&gt; System.IComparable&lt;'a&gt; =
 | EmptyTree
 | TreeNode of 'a * 'a tree * 'a tree
 module Tree =
 let rec insert (x : #System.IComparable&lt;'a&gt;) = function
 | EmptyTree -&gt; TreeNode(x, EmptyTree, EmptyTree)
 | TreeNode(y, l, r) as node -&gt;
 match x.CompareTo(y) with
 | 0 -&gt; node
 | 1 -&gt; TreeNode(y, l, insert x r)
 | -1 -&gt; TreeNode(y, insert x l, r)
 | _ -&gt; failwith "CompareTo returned illegal value"
Since we have a leading namespace declaration in both files, F# does not create any implicit modules. The codice_44, codice_45, codice_46, and codice_47 types are all accessible through the codice_39 namespace:
Program.fs
open Princess.Collections
let x = Stack.getRange 1 10
let y =
 let rnd = new System.Random()
 [ for a in 1 .. 10 -&gt; rnd.Next(0, 100) ]
 |&gt; Seq.fold (fun acc x -&gt; Tree.insert x acc) EmptyTree
printfn "%A" (Stack.hd x)
printfn "%A" (Stack.tl x)
printfn "%A" (Stack.fold ( * ) 1 x)
printfn "%A" (Stack.reduce ( + ) x)
printfn "%A" y
Controlling Class and Module Accessibility.
Unlike modules, there is no equivalent to a signature file for namespaces. Instead, the visibility of classes and submodules is controlled through standard accessibility modifiers:
namespace Princess.Collections
 type 'a tree when 'a :&gt; System.IComparable&lt;'a&gt; =
 | EmptyTree
 | TreeNode of 'a * 'a tree * 'a tree
 (* InvisibleModule is only accessible by classes or
 modules inside the Princess.Collections namespace*)
 module private InvisibleModule =
 let msg = "I'm invisible!"
 module Tree =
 (* InvisibleClass is only accessible by methods
 inside the Tree module *)
 type private InvisibleClass() =
 member x.Msg() = "I'm invisible too!"
 let rec insert (x : #System.IComparable&lt;'a&gt;) = function
 | EmptyTree -&gt; TreeNode(x, EmptyTree, EmptyTree)
 | TreeNode(y, l, r) as node -&gt;
 match x.CompareTo(y) with
 | 0 -&gt; node
 | 1 -&gt; TreeNode(y, l, insert x r)
 | -1 -&gt; TreeNode(y, insert x l, r)
 | _ -&gt; failwith "CompareTo returned illegal value"