Skip to content

Instantly share code, notes, and snippets.

@enricopolanski
Last active May 25, 2020 12:36
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save enricopolanski/006761d2a20222bd0f8082934dcfae4e to your computer and use it in GitHub Desktop.
Save enricopolanski/006761d2a20222bd0f8082934dcfae4e to your computer and use it in GitHub Desktop.
Equivalence #1

Suppose we want a set of unique { x, y } points to plot on a graph.

this expression:

new Set([
  { x: 1, y: 1 },
  { x: 1, y: 1 },
]);

evaluates to: Set { { x: 1, y: 1}, { x : 1, y: 1} } which is likely not what we want.

Let's see the signature of the same constructor in the Set module contained in the fp-ts library:

declare const fromArray: <A>(E: Eq<A>) => (as: Array<A>) => Set<A>;

where the Eq typeclass is defined as:

interface Eq<A> {
  readonly equals: (x: A, y: A) => boolean;
}

Thus, fromArray takes first an Eq instance where it is up to the consumer to specify the meaning of the equivalence in his particular domain.

interface Point {
  x: number;
  y: number;
}
const eqPoint: Eq<Point> = {
  equals: (p1, p2) => p1 === p2 || (p1.x === p2.x && p1.y === p2.y),
};

We have defined what does it means for two points to be equal. They are either the same point (by reference), or they have the same coordinates

fromArray(eqPoint)([
  { x: 1, y: 1 },
  { x: 1, y: 1 },
]);

Now correctly evaluates to Set { { x: 1, y: 1} }

Takeaway: the concept of equivalence is vague and it is often a good idea to encode it's meaning in our domain business.

@imcotton
Copy link

imcotton commented May 25, 2020

A little bit of improvement:

const eqPoint = Eq.getStructEq<Point>({
  x: Eq.eqNumber,
  y: Eq.eqNumber,
});

@enricopolanski
Copy link
Author

A little bit of improvement:

const eqPoint = Eq.getStructEq<Point>({
  x: Eq.eqNumber,
  y: Eq.eqNumber,
});

Absolutely, didn't write it like that to make it obvious for people that aren't accustomed to the Eq typeclass what was happening.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment