Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // @flow
- type NoneType = {|
- type: 'None',
- |};
- type AppleType<AppleInner> = {|
- type: 'Apple',
- value: AppleInner,
- |};
- type BananaType = {|
- type: 'Banana',
- value: number,
- |};
- type DisjointUnion<AppleInner> = NoneType | AppleType<AppleInner> | BananaType;
- export default class MaybeFruit<AppleInner> {
- type: $PropertyType<DisjointUnion<AppleInner>, 'type'>;
- value: $PropertyType<DisjointUnion<AppleInner>, 'value'>;
- constructor(data: DisjointUnion<AppleInner>) {
- Object.assign(this, data);
- }
- static None: MaybeFruit<any> = new MaybeFruit({
- type: 'None',
- });
- static Apple = <OtherAppleInner>(
- value: OtherAppleInner
- ): MaybeFruit<OtherAppleInner> =>
- new MaybeFruit({
- type: 'Apple',
- value,
- });
- static Banana = (value: number): MaybeFruit<any> =>
- new MaybeFruit({type: 'Banana', value});
- match<NoneResult, AppleResult, BananaResult, DefaultResult>(
- // You need to specify either a handler for every case,
- // or a default handler and a handler for some cases.
- matchObj:
- | {|
- None: () => NoneResult,
- Apple: (value: AppleInner) => AppleResult,
- Banana: (value: number) => BananaResult,
- |}
- | {|
- None?: () => NoneResult,
- Apple?: (value: AppleInner) => AppleResult,
- Banana?: (value: number) => BananaResult,
- _: (...args: Array<mixed>) => DefaultResult,
- |}
- ): NoneResult | AppleResult | BananaResult | DefaultResult {
- const self = ((this: any): DisjointUnion<AppleInner>);
- if (self.type === 'None') {
- return (matchObj.None || matchObj._)();
- } else if (self.type === 'Apple') {
- return (matchObj.Apple || matchObj._)(self.value);
- } else if (self.type === 'Banana') {
- return (matchObj.Banana || matchObj._)(self.value);
- } else {
- (self: empty);
- }
- }
- }
Add Comment
Please, Sign In to add comment