Skip to content

Instantly share code, notes, and snippets.

@zaetrik
Last active May 4, 2020 13:42
Show Gist options
  • Save zaetrik/da79e2c90cfeda80d061d36f8baf2a56 to your computer and use it in GitHub Desktop.
Save zaetrik/da79e2c90cfeda80d061d36f8baf2a56 to your computer and use it in GitHub Desktop.
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;
}
// We create a Eq<number> instance
const eqNumber: Eq<number> = {
equals: (x, y) => x === y
}
// contramap takes in a function that takes in something of type B and returns something of type A
// It then returns a function that takes in something of type Eq<A> and returns a new Eq<B>
const contramap = <A, B>(f: (b: B) => A) => (E: Eq<A>): Eq<B> => {
return {
equals: (x, y) => E.equals(f(x), f(y))
}
}
type Artist = {
artistId: number;
name: string;
};
// Two artists are equal if their `artistId` field is equal
const eqArtist: Eq<Artist> = contramap((artist: Artist) => artist.artistId)(eqNumber);
// We can now pass in two Artist objects and check for equality
eqArtist.equals({ artistId: 1, name: "EDEN" }, { artistId: 1, name: "eden" }); // true
eqArtist.equals({ artistId: 1, name: "ATO" }, { artistId: 2, name: "ATO" }); // false
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment