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
  • Types Composition
  • Creating new types
  • Combine 2 unions?
  • Union (FP) vs Object Hierarchy (OOP)
  • Explanations
  • FP vs OOP
  • FP vs OOP: Open-Closed Principle

Was this helpful?

Edit on GitHub
  1. Types

Addendum

Types Composition

Creating new types

Algebraic data types do not support inheritance

  • They cannot inherit from a base class.

  • They are sealed: they cannot be inherited.

  • But they can implement interfaces.

Algebraic types are created by composition:

  • Aggregation into a product type (Record, Tuple)

  • "Choice" in a sum type (Union)

Combine 2 unions?

Consider the 2 unions below dealing with French-suited cards (♠ ♣ ♥ ♦):

type Black = Pike | Club
type Red = Heart | Tile

How do you combine them to create a union of Pike, Club, Heart or Tile?

By flattening unions, as in TypeScript ❌

type Color = Black | Red

→ It's not the expected result: Color is an enum-style union, with 2 cases Black and Red, totally disconnected from the Black and Red types!

By creating a brand new union ⚠️

type Color = Pike | Club | Hear | Tile
let pike = Pike

Warnings

  • Can create confusion: Pike refers to Color.Pike or Black.Pike?

  • Need to write mappers between the 2 models: (Black, Red) <-> Color

By composition ✅

type Color = Black of Black | Red of Red
let pike = Black Pike

→ The new union Color is composed based on the 2 previous types:

  • Black union is used as data for the Color.Black case

  • Red union is used as data for the Color.Red case

Note

It's common in F♯ to write union cases like Black of Black where the case name matches the case field type.

Union (FP) vs Object Hierarchy (OOP)

👉 A union can usually replace a small object hierarchy.

Explanations

Behaviors/operations implementation:

  • OO: virtual methods in separate classes

  • FP: functions relying on pattern matchings

    • exhaustivity

    • avoid duplication by grouping cases

    • improve readability by flattening split cases in a single match..with

FP vs OOP

How we reason about the code (at both design and reading time)

  • FP: by functions → how an operation is performed for the different cases

  • OO: by objects → how all operations are performed for a single case

Abstraction

  • Objects are more abstract than functions

  • Good abstraction is difficult to design

  • The more abstract a thing is, the more stable it should be

👉 FP is usually easier to write, to understand, to evolve

FP vs OOP: Open-Closed Principle

It's easier to extend what's open.

OO: open hierarchy, closed operations

  • Painful to add an operation: in all classes 😓

  • Easy to add a class in the hierarchy 👍

FP: open operations, closed cases

  • Easy to add an operation 👍

  • Painful to add a case: in all functions 😓

    • Still, it's usually easier in F♯: only 1 file to change

☝️ Notes:

  • Adding a class = new concept in the domain → always tricky ⚠️

  • Adding an operation = new behavior for the existing domain concepts

PreviousRecapNextIntro

Last updated 1 month ago

Was this helpful?