Effect-TS / data

Custom built data types leveraged by the Effect ecosystem
https://effect.website
MIT License
184 stars 22 forks source link

Traits for the greater good #270

Open mikearnaldi opened 1 year ago

mikearnaldi commented 1 year ago

We currently have the following traits:

We can see traits as typeclasses that are directly implemented in the data rather than presented as separated instances, they have the advantage of not requiring to pass explicitly instances and can make DX better.

There are other scenarios that came up as useful, those are:

Note: The ones marked with * are coming from requirements in optics.

mikearnaldi commented 1 year ago

cc @patroza @gcanti @IMax153 @pigoz

patroza commented 1 year ago

so far what seems to work well is Object.setPrototypeOf(copy, Object.getPrototypeOf(original)). for Data.struct, classes in general, and for Data.Class etc. Perhaps using that as a default, with the ability to override via a copy trait, would be a good way forward.

See https://github.com/patroza/optic/pull/1/files

patroza commented 1 year ago

cloning with private fields gets a little hairy...

  test("some private", () => {
    class ABC {
      [Optic.cloneTrait](a: any) {
        const cl = new ABC(a.a, a.b)
        cl.#test = this.#test
        return cl // Object.assign(Object.create(this), a)
      }
      #test: number
      constructor(readonly a: number, readonly b: number) {
        this.#test = 1
      }

      set test(v: number) {
        this.#test = v
      }

      get test() {
        return this.#test
      }
    }
    const opt = Optic.id<ABC>()
    const v = new ABC(1, 2)
    v.test = 2

    const v2 = Optic.replace(opt.at("a"))(1)(v)
    expect(v.test).toBe(2)
    expect(v2.test).toBe(2)
  })

but its a general problem with private fields.