Guest User

Untitled

a guest
Dec 15th, 2018
118
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 1.82 KB | None | 0 0
  1. // @flow
  2. type NoneType = {|
  3. type: 'None',
  4. |};
  5. type AppleType<AppleInner> = {|
  6. type: 'Apple',
  7. value: AppleInner,
  8. |};
  9. type BananaType = {|
  10. type: 'Banana',
  11. value: number,
  12. |};
  13.  
  14. type DisjointUnion<AppleInner> = NoneType | AppleType<AppleInner> | BananaType;
  15.  
  16. export default class MaybeFruit<AppleInner> {
  17. type: $PropertyType<DisjointUnion<AppleInner>, 'type'>;
  18. value: $PropertyType<DisjointUnion<AppleInner>, 'value'>;
  19.  
  20. constructor(data: DisjointUnion<AppleInner>) {
  21. Object.assign(this, data);
  22. }
  23.  
  24. static None: MaybeFruit<any> = new MaybeFruit({
  25. type: 'None',
  26. });
  27.  
  28. static Apple = <OtherAppleInner>(
  29. value: OtherAppleInner
  30. ): MaybeFruit<OtherAppleInner> =>
  31. new MaybeFruit({
  32. type: 'Apple',
  33. value,
  34. });
  35.  
  36. static Banana = (value: number): MaybeFruit<any> =>
  37. new MaybeFruit({type: 'Banana', value});
  38.  
  39. match<NoneResult, AppleResult, BananaResult, DefaultResult>(
  40. // You need to specify either a handler for every case,
  41. // or a default handler and a handler for some cases.
  42. matchObj:
  43. | {|
  44. None: () => NoneResult,
  45. Apple: (value: AppleInner) => AppleResult,
  46. Banana: (value: number) => BananaResult,
  47. |}
  48. | {|
  49. None?: () => NoneResult,
  50. Apple?: (value: AppleInner) => AppleResult,
  51. Banana?: (value: number) => BananaResult,
  52. _: (...args: Array<mixed>) => DefaultResult,
  53. |}
  54. ): NoneResult | AppleResult | BananaResult | DefaultResult {
  55. const self = ((this: any): DisjointUnion<AppleInner>);
  56.  
  57. if (self.type === 'None') {
  58. return (matchObj.None || matchObj._)();
  59. } else if (self.type === 'Apple') {
  60. return (matchObj.Apple || matchObj._)(self.value);
  61. } else if (self.type === 'Banana') {
  62. return (matchObj.Banana || matchObj._)(self.value);
  63. } else {
  64. (self: empty);
  65. }
  66. }
  67. }
Add Comment
Please, Sign In to add comment