gcanti / fp-ts

Functional programming in TypeScript
https://gcanti.github.io/fp-ts/
MIT License
10.66k stars 504 forks source link

ADTs Guide #1326

Open SRachamim opened 3 years ago

SRachamim commented 3 years ago

📖 Documentation

In the documentation there's a suggestion on how to implement ADTs with TypeScript:

interface Bar {
  readonly _tag: 'Bar'
  readonly value: string
}

interface Baz {
  readonly _tag: 'Baz'
  readonly value: boolean
}

// type
type Foo = Bar | Baz

// constructors
const Bar = (value: string): Foo => ({ _tag: 'Bar', value })

const Baz = (value: boolean): Foo => ({ _tag: 'Baz', value })

I wonder why can't we use classes instead? They come with a constructor for free:

class Bar {
  readonly _tag = 'Bar';
  constructor(readonly value: string) {}
}

class Baz {
  readonly _tag = 'Baz';
  constructor(readonly value: boolean) {}
}

// type
type Foo = Bar | Baz

What can go wrong and what are the limitations of this approach?

raveclassic commented 3 years ago

Class-based approached was abandoned in previous versions of fp-ts because of limitations of js/ts.

mikearnaldi commented 3 years ago

@SRachamim I usually use classes as members of ADTs as you described and I am not aware of any limitation.

The class-based approach in reference above from which fp-ts migrated away refers to fluent APIs that are indeed very problematic.