Introduction
fp-ts is a library that enables to use functional programming in typescript.
There is an ecosystem of libraries that revolves around it. Once you can use fp-ts you can use those as well.
fp-ts implements notions and concepts from functional programming. The two pillars that are essential to understand how to use it are the following:
Referential transparency
Composition (as a design pattern)
Let's talk more in depth on what those two pillars are
Referential Transparency
This is a very simple but powerful concept. It states as follows: Everything is an Expression. When something is an Expression you can safely replace it with its corresponding value without changing the Program's behavior.
This concept is very powerful when refactoring.
To achieve this effect some rules have to be enforced.
Functions need to be pure
What does "to be pure" mean? A function is pure when it doesn't have side effects, takes in input all parameters that are needed and returns a value. Let's analyze what this means.
Doesn't have side effects
A side effect is a change outside the function, the most common way is to update an external variable. Another one is a function that may throw an error.
Think whether replaceing that function with its value will update the external variable or throw the exception
Let's analyze the case of the external variable
now we perform the substitution and see what happens
as you can see the result is changed, what can we do to rectify this?
now if we replace the function sum with its result the program doesn't change.
if the function throws an error the concept is similar
Now the program behavior changes when we replace the function with its result
All parameters are in input
This is in a similar vein as before, a function needs to be able to work without external values. For example let's assume that we have a global variable and a function that depends on said global variable
Now if we move the function in a new file it doesn't work anymore
to make this function pure we need to make the dependency explicit
This aids readability and testability of the function
Returns a value
This particular point is not so obvious, usually if something has a void
return it usually means that some side effect is performed. It's in the same vein as before, portability and testability.
To perform side effect take a look at IO
Composition
Composition is a pattern that enables the construction of bigger and complex entities by combining smaller and easier to understand units that do something very specific.
Combinators
This is taken straight from Haskell
A style of organizing libraries centered around the idea of combining things. Usually there is some type
T
, some "primitive" values of typeT
, and some "combinators" which can combine values of typeT
in various ways to build up more complex values of typeT
The general form of a combinator is:
The purpose of a combinator is to create new "things" from "things" that are already defined.
The result can be passed as an input and we get an explosion of combinatorial possibilities, this is the power of this pattern.
If we mix different combinators together the resulting combinatorial explosion is even greater.
So the general design that you will find in a functional module is achieved by using the following points:
a group of simple "primitives"
a group of combinators to combine said primitives in more complex structures
Last updated