F# Training
F# Training
F# Training
  • Presentation
  • Fundamentals
    • Introduction
    • Syntax
      • Bases
      • Functions
      • Rules
      • Exceptions
    • First concepts
    • šŸ”Quiz
  • Functions
    • Signature
    • Concepts
    • Syntax
    • Standard functions
    • Operators
    • Addendum
    • šŸ”Quiz
    • šŸ“œSummary
  • Types
    • Overview
    • Tuples
    • Records
    • Unions
    • Enums
    • Anonymous records
    • Value types
    • šŸ“œRecap
    • Addendum
  • Monadic types
    • Intro
    • Option type
    • Result type
    • Smart constructor
    • šŸš€Computation expression (CE)
    • šŸš€CE theoretical basements
    • šŸ“œRecap
  • Pattern matching
    • Patterns
    • Match expression
    • Active patterns
    • šŸš€Fold function
    • šŸ“œRecap
    • šŸ•¹ļøExercises
  • Collections
    • Overview
    • Types
    • Common functions
    • Dedicated functions
    • šŸ”Quiz
    • šŸ“œRecap
  • Asynchronous programming
    • Asynchronous workflow
    • Interop with .NET TPL
    • šŸ“œRecap
  • Module and Namespace
    • Overview
    • Namespace
    • Module
    • šŸ”Quiz
    • šŸ“œRecap
  • Object-oriented
    • Introduction
    • Members
    • Type extensions
    • Class, Struct
    • Interface
    • Object expression
    • Recommendations
Powered by GitBook
On this page
  • Similarities
  • Differences
  • Use a module or a namespace
  • Imports order
  • Shadowing at import
  • Keyword global

Was this helpful?

Edit on GitHub
  1. Module and Namespace

Overview

Similarities

Modules and namespaces allow you to:

  • Organize code into zones of related functionality

  • Avoid name collisions

Differences

Property
Namespace
Module

.NET equivalent

namespace

static class

Type

Top-level

Top-level or local

Contains

Modules, Types

Idem + Values, Functions

Annotable

āŒ No

āœ… Yes

Scope: Namespaces > Files > Modules

Use a module or a namespace

  1. Either qualify the elements individually

  2. Or import everything with the open keyword

    • placed anywhere before the usage, at the top recommended

    • open Name.Space ≔ C♯ using Name.Space

    • open My.Module ≔ C♯ using static My.Module

// Option 1: Qualify usages
let result1 = Arithmetic.add 5 9

// Option 2: Import the entire module
open Arithmetic
let result2 = add 5 9

Imports order

āš ļø Warning: the order of the imports is taken into account, from top to bottom.

  • This allows shadowing (see below).

  • As a result, reordering imports in an existing file may cause compilation to fail!

  • So, although it's advisable to have imports sorted alphabetically, this isn't always possible. It is therefore advisable to indicate this in the code by means of a comment.

Shadowing at import

Imports are done without name conflicts but need disambiguation:

  • Modules and static classes are merged āœ…

  • Types and functions are shadowed ā— - Last-imported-wins mode: see example below - Import order matters

module IntHelper =
    let add x y = x + y

module FloatHelper =
    let add x y : float = x + y

open IntHelper
open FloatHelper // šŸ‘ˆ IntHelper add is shadowed by FloatHelper add

let result = add 1 2 // šŸ’„ Error FS0001: The type 'float' does not match the type 'int'

ā˜ Recommendation

Shadowing is more likely to happen with common names such as add in the previous example, or map, filter... from the List, Seq... modules.

Qualification is recommended in this case, and it can be made mandatory by decorating the module with [<RequireQualifiedAccess>]šŸ“

Keyword global

Because of Shadowing, we may come across cases where we can't import the right namespace. For example, having done open FsCheck and referenced the FsCheck.Xunit library, when you do open Xunit, we don't import the Xunit namespace from the Xunit library but the FsCheck.Xunit namespace!

šŸ’” We resolve fix issue by doing open global.Xunit.

PreviousRecapNextNamespace

Last updated 1 month ago

Was this helpful?