2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

class だけ異なる値を Set で扱いたい

Posted at

fp-ts で実現可能なことを確認しました。

Literal.ts
export type Literal = StringLiteral | NumberLiteral;

export class StringLiteral {
  constructor(readonly value: string) {}
}

export class NumberLiteral {
  constructor(readonly value: string) {}
}
literals.ts
import * as Set from "fp-ts/Set";
import { type Eq } from "fp-ts/Eq";
import { type Literal, StringLiteral, NumberLiteral } from "./Literal";

const literalArray = [
  new StringLiteral("42"),
  new StringLiteral("42"),
  new NumberLiteral("42"),
  new NumberLiteral("42"),
];

const standardLiteralSet = new global.Set<Literal>(literalArray);
console.log("standard", standardLiteralSet);

const eqLiteral: Eq<Literal> = {
  equals: (x, y) => {
    return (
      ((x instanceof StringLiteral && y instanceof StringLiteral) ||
        (x instanceof NumberLiteral && y instanceof NumberLiteral)) &&
      x.value === y.value
    );
  },
};

const fpTsLiteralSet = Set.fromArray<Literal>(eqLiteral)(literalArray);
console.log("fp-ts", fpTsLiteralSet);

実行結果は以下の通りで、標準の Set では重複を排除できませんが、fp-ts の Set では比較に使う Eq を独自定義することで class と value の両方が一致するものは重複として排除されています。

standard Set(4) {
  StringLiteral {
    value: "42",
  },
  StringLiteral {
    value: "42",
  },
  NumberLiteral {
    value: "42",
  },
  NumberLiteral {
    value: "42",
  },
}
fp-ts Set(2) {
  StringLiteral {
    value: "42",
  },
  NumberLiteral {
    value: "42",
  },
}
2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?