mw10013 / effect_sandbox

0 stars 0 forks source link

Effect<R, E, A> #4

Open mw10013 opened 11 months ago

mw10013 commented 11 months ago
// Effect.ts
import * as core from "./internal/core.js"

export interface Effect<R, E, A> extends Effect.Variance<R, E, A>, Equal.Equal, Pipeable {
  readonly [Unify.typeSymbol]?: unknown
  readonly [Unify.unifySymbol]?: EffectUnify<this>
  readonly [Unify.ignoreSymbol]?: EffectUnifyIgnore
}

  export interface Variance<R, E, A> {
    readonly [EffectTypeId]: VarianceStruct<R, E, A>
  }

  export interface VarianceStruct<R, E, A> {
    readonly _V: string
    readonly _R: (_: never) => R
    readonly _E: (_: never) => E
    readonly _A: (_: never) => A
  }

  export type Context<T extends Effect<any, any, any>> = [T] extends [Effect<infer _R, infer _E, infer _A>] ? _R : never
  export type Error<T extends Effect<any, any, any>> = [T] extends [Effect<infer _R, infer _E, infer _A>] ? _E : never
  export type Success<T extends Effect<any, any, any>> = [T] extends [Effect<infer _R, infer _E, infer _A>] ? _A : never
mw10013 commented 11 months ago
// Effect.ts
import * as core from "./internal/core.js"

export const succeed: <A>(value: A) => Effect<never, never, A> = core.succeed

// internal/core.ts

export const succeed = <A>(value: A): Effect.Effect<never, never, A> => {
  const effect = new EffectPrimitiveSuccess(OpCodes.OP_SUCCESS) as any
  effect.i0 = value
  return effect
}

class EffectPrimitiveSuccess {
  public i0 = undefined
  public i1 = undefined
  public i2 = undefined
  public trace = undefined;
  [EffectTypeId] = effectVariance
  constructor(readonly _op: Primitive["_op"]) {
    // @ts-expect-error
    this._tag = _op
  }
  [Equal.symbol](this: {}, that: unknown) {
    return this === that
  }
  [Hash.symbol](this: {}) {
    return Hash.random(this)
  }
  get value() {
    return this.i0
  }
  pipe() {
    return pipeArguments(this, arguments)
  }
  toJSON() {
    return {
      _id: "Exit",
      _tag: this._op,
      value: toJSON(this.value)
    }
  }
  toString() {
    return toString(this.toJSON())
  }
  [NodeInspectSymbol]() {
    return this.toJSON()
  }
}