Skip to content

Instantly share code, notes, and snippets.

@zaetrik
zaetrik / monoid-fold.ts
Created May 4, 2020 13:14
Monoid Type Class Fold
// We can use the fold function to concatenate/merge an array of values
// with the concat method defined for the Monoid instance
// The fold function gets a little bit easier when using it with Monoids
// Let's take a look at the fp-ts implementation of fold for Monoids
export function fold<A>(M: Monoid<A>): (as: ReadonlyArray<A>) => A {
const foldM = foldSemigroup(M)
return (as) => foldM(M.empty, as)
}
// We see that the fold function for Monoids uses the fold function for Semigroups
@zaetrik
zaetrik / monoid-introduction.ts
Created May 4, 2020 13:00
Monoid Type Class Introduction
// Monoid type class
// Used to merge two contexts together
// Mostly taken from https://dev.to/gcanti/getting-started-with-fp-ts-monoid-ja0
// A Monoid extends the Semigroup type class
// "A Monoid is any Semigroup that happens to have a special value which is "neutral" with respect to concat" - https://dev.to/gcanti/getting-started-with-fp-ts-monoid-ja0
// empty does nothing else than returning that special neutral value
interface Monoid<A> extends Semigroup<A> {
readonly empty: A
}
@zaetrik
zaetrik / semigroup-objects.ts
Last active May 3, 2020 09:25
Semigroup Type Class Objects
type Song = {
releaseYear: number;
title: string;
artistId: number;
};
// We could also create a Semigroup instance for objects
const semigroupSong: Semigroup<Song> = {
concat: (song1: Song, song2: Song) => ({
releaseYear: song1.releaseYear > song2.releaseYear ? song1.releaseYear : song2.releaseYear, // keep the most recent year
@zaetrik
zaetrik / semigroup-merging-option.ts
Created May 3, 2020 08:46
Semigroup Type Class Merging Option<A>
// Merging two numbers or strings together is pretty easy
// but what if we would like to merge values that are wrapped inside a context like Option<A>?
// We need some special logic for that
// fp-ts exports a function that lets you create a Semigroup instance for an Option<A>
// What it does is check if both, x & y, are not `none`
// and if so it takes the the values from x & y and applies them to the concat method of the Semigroup instance we passed into getApplySemigroup
export function getApplySemigroup<A>(S: Semigroup<A>): Semigroup<Option<A>> {
return {
concat: (x, y) => (isSome(x) && isSome(y) ? some(S.concat(x.value, y.value)) : none)
@zaetrik
zaetrik / semigroup-fold.ts
Created May 3, 2020 08:34
Semigroup Type Class fold
// Semigroup's concat works only with two values
// If we would like to merge/concat more elements we have to use a function called fold
// If you understand JS's array.reduce you will understand fold
// The fold function for Semigroups from fp-ts is defined like this =>
export function fold<A>(S: Semigroup<A>): (a: A, as: ReadonlyArray<A>) => A {
return (a, as) => as.reduce(S.concat, a)
}
// It takes in a Semigroup and returns a function that takes in an initial value A and an array of A (Array<A>) and returns an A
// So it folds/reduces an Array<A> into a single value A
@zaetrik
zaetrik / semigroup-introduction.ts
Last active May 3, 2020 11:00
Semigroup Type Class Introduction
// Semigroup type class
// Used to merge two contexts together
// Mostly taken from https://dev.to/gcanti/getting-started-with-fp-ts-semigroup-2mf7
// Our interface for the Semigroup type class
// For something to be a member of the Semigroup type class it has to implement a concat method
// that "merges" two As together and returns a new A
// concat has to be associative, which means => (x * y) * z = x * (y * z)
interface Semigroup<A> {
concat: (x: A, y: A) => A
@zaetrik
zaetrik / ord-extended.ts
Last active May 4, 2020 13:43
Ord Type Class Extended
// Mostly taken from https://dev.to/gcanti/getting-started-with-fp-ts-ord-5f1e
// Now we could create min & max functions
function min<A>(O: Ord<A>): (x: A, y: A) => A {
return (x, y) => (O.compare(x, y) === 1 ? y : x);
}
function max<A>(O: Ord<A>): (x: A, y: A) => A {
return (x, y) => (O.compare(x, y) === 1 ? x : y);
}
@zaetrik
zaetrik / ord.ts
Last active May 4, 2020 13:43
Ord Type Class
// Ord type class
// => used for ordering things it contains types that admit a total ordering
// Mostly taken from https://dev.to/gcanti/getting-started-with-fp-ts-ord-5f1e
// -1 is for x < y
// 0 is for x === y
// 1 is for x > 1
type Ordering = -1 | 0 | 1
// Our interface for the Ord type class
@zaetrik
zaetrik / eq-extended.ts
Created May 2, 2020 16:50
Eq Type Class Extenden
type Album = {
artist: Artist;
title: string;
albumId: number;
};
const eqAlbumBySameArtist: Eq<Album> = contramap((album: Album) => album.artist)(eqArtist);
// Now we can check if an album is made by the same artist
eqAlbumBySameArtist.equals(
@zaetrik
zaetrik / eq.ts
Last active May 4, 2020 13:42
Eq Type Class
// Eq type class
// => used to compare two inputs and check for equality
// Mostly taken from https://dev.to/gcanti/getting-started-with-fp-ts-setoid-39f3
// Our interface for the Eq type class
// For something to be a member of the Eq type class it has to implement an equals method that returns true
interface Eq<A> {
// `true` if `x` equals `y`
readonly equals: (x: A, y: A) => boolean;
}