# Algebric Datatypes in Javascript ( Sorry I usually write all my notes in MarkDown .MD format)
---
1. The functional programming provides the features of **monoids** and **monoids functors**.
2. Their are two types Algebric datatypes
- Product Types
- Sum Types
3. Products of types represents a conjunction "and", of those types.
```typescript
class pair<U, V> {
constructor(public x: U, public y: V) {}
}
```
> Pair is a product of types U and V which are just placeholders and can be of any types like:Pair<Boolean,Number> or Pair<String,Function>,etc.
```Typescript
class Triple<U,V,W>{
constructor(
public x:U,
public y:V,
public z:W
){}
}
class Box<T>{
constructor(
private _val:T,
){}
/* Methods */
}
// Generics are not measured for product types
class Person{
constructor(
public name:String,
public age:Number
)
}
```
> The Main principle of Algebric Datatypes is being equalish(Isomorphic) .i.e **set A is not equal to set B, but they have same information**
>
> > Thus we can say that Pair<U,V> is not equal to Pair<V,U> but has the same information
`If we try to compare the functions they will cause compile time error, but they have same information`
```typescript
function swap<U,V>(pair:Pair<U,V>:Pair<V,U>){
return new Pair<V,U>(pair.y,pair.x)
}
```
`Mathematical Proof: The order you define members of your data structure`
> Associativity : a _ (b _ c) == (a * b)*c
We can define a function that transforms first type into second and vice versa
```Typescript
function associate<U, V, W>(pair: Pair<U, Pair<V, W>>): Pair<Pair<U, V>, W> {
return new Pair<Pair<U, V>, W>(
new Pair<U, V>(
pair.x,
pair.y.x,
),
pair.y.y
)
}
function associateReversed<U, V, W>(pair: Pair<Pair<U, V>, W>): Pair<U, Pair<V, W>> {
/* ... */
}
```
## Identity : n\*1 == n
> So what would be identity(like 1 for numbers) for Product Types..?
>
> > In Typescript and Javascript it is null and undefined are in void type
> > Pair<U,void> is not equal to U but they have same information
FYI : in the functional world it would be called Unit which is a type with only one possible value(like void in Typescript which could be counted as one value). The void type in the functinal world is the type with no possible values
```Typescript
function unit<U>(pair:Pair<U,void>):U{
return pair.x
}
function unitReverse<U>(value:U):Pair<U,void>{
return new Pair(value,undefined)
Recommended by LinkedIn
}
```
`This shows that the Product data types and number have same properties .i.e. associativity,identity and symmetry`
```Typescript
// Now look at the sum of types(also called as tagged union). Sums of types represent a disjuncion or of those types
interface Either<U,V>{}
class Left<U,V> implements Either<U,V> {
constructor(public x:U){}
}
class Right<U,V> implements Either<U,V> {
constructor(public x : V)
}
```
`Another way of writing the same code`
```typescript
class Left<U>{
constructor(public x:U)
}
class Right<V>{
constructor(public x:V)
}
type Either<U,V> = Left<U> | Right<V>
// or :
class TypeError<T>{
/* */
}
class SyntaxError<T>{
/* */
}
type Error<U,V> = TypeError<U> | SyntaxError<V>
```
It can be read as `Errors<U,V>` can be either `TypeError<U` or `SyntaxError<V>`
> As addition and Multiplication, Sum and Product types share properties too. Sum and types also have three properties describe above
Now let's see what happens when we mix sum and product types mixed:
e.g. `Pair<U,Either<V,W>>` let analyze it for a moment, We have `U` type and `Either<V,W>` which means we have:`u` and (`Left<V>` and `Right<W>`) and what are the possible outcomes? `Pair<U,Left<V>>` or `Pair<U,Right<W>>` this looks like distrubutive property right? `a * (b+c) = a * b + a * c`
## The real reason for name Algebric data types
---
Let's define list class which is either a `Nil(empty list)` or `cons` the head and tail of the list, it's recursive data structure
```typescript
// l(x) = 1 + x * l(x)
// Empty List
type List<T> = Nil | Cons<T>
// head and tail
class Cons<T>{
constructor(
private x:T,
private xs: List<T>
){}
}
```
We can use it like this
```typescript
const emptyList: List<Number> = new Nil()
const l1:List<Number> = new Cons(1,
new Cons(
2,
new Cons(
3,
new Cons(
4,
new Nil()
)
)
)
)
// 1 -> 2 -> 3 -> 4 -> Nil
l1.head() // 1
l1.tail() // 2 -> 3 -> 4 -> Nil
```
We can convert `list` class into a algebric equation : `l(x) = 1 + x * l(x) = 1 + x * (1 + x * l(x)) = 1 + x + x * l(x)` where `1` is like `Nil` and `x * l(x)` is like `Cons(x,list)`