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 (â ⣠⼠âŚ):
How do you combine them to create a union of Pike
, Club
, Heart
or Tile
?
By flattening unions, as in TypeScript â
â 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 â ď¸
Warnings
Can create confusion:
Pike
refers toColor.Pike
orBlack.Pike
?Need to write mappers between the 2 models:
(Black, Red) <-> Color
By composition â
â The new union Color
is composed based on the 2 previous types:
Black
union is used as data for theColor.Black
caseRed
union is used as data for theColor.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
Last updated
Was this helpful?