Skip to content

Commit

Permalink
feat: Make Equal an implicit trait, namely remove the type Data.Data (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
mikearnaldi authored and tim-smart committed Feb 9, 2024
1 parent 6361ee2 commit 02c3461
Show file tree
Hide file tree
Showing 23 changed files with 194 additions and 197 deletions.
33 changes: 33 additions & 0 deletions .changeset/mighty-donuts-behave.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
---
"@effect/platform": minor
"effect": minor
"@effect/schema": minor
"@effect/cli": minor
"@effect/rpc": minor
---

With this change we remove the `Data.Data` type and we make `Equal.Equal` & `Hash.Hash` implicit traits.

The main reason is that `Data.Data<A>` was structurally equivalent to `A & Equal.Equal` but extending `Equal.Equal` doesn't mean that the equality is implemented by-value, so the type was simply adding noise without gaining any level of safety.

The module `Data` remains unchanged at the value level, all the functions previously available are supposed to work in exactly the same manner.

At the type level instead the functions return `Readonly` variants, so for example we have:

```ts
import { Data } from "effect";

const obj = Data.struct({
a: 0,
b: 1,
});
```

will have the `obj` typed as:

```ts
declare const obj: {
readonly a: number;
readonly b: number;
};
```
4 changes: 2 additions & 2 deletions packages/cli/src/Options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -177,13 +177,13 @@ export const choice: <A extends string, C extends ReadonlyArray<A>>(
*
* export type Animal = Dog | Cat
*
* export interface Dog extends Data.Case {
* export interface Dog {
* readonly _tag: "Dog"
* }
*
* export const Dog = Data.tagged<Dog>("Dog")
*
* export interface Cat extends Data.Case {
* export interface Cat {
* readonly _tag: "Cat"
* }
*
Expand Down
34 changes: 17 additions & 17 deletions packages/effect/dtslint/Data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@ declare const mutableArray: Array<string>
// struct
// -------------------------------------------------------------------------------------

// $ExpectType Data<{ readonly a: string; }>
// $ExpectType { readonly a: string; }
const struct1 = Data.struct(mutableStruct)

// @ts-expect-error
struct1.a = "a"

// $ExpectType Data<{ readonly a: string; }>
// $ExpectType { readonly a: string; }
const struct2 = Data.struct(readonlyStruct)

// @ts-expect-error
Expand All @@ -26,13 +26,13 @@ struct2.a = "a"
// unsafeStruct
// -------------------------------------------------------------------------------------

// $ExpectType Data<{ readonly a: string; }>
// $ExpectType { readonly a: string; }
const struct3 = Data.unsafeStruct(mutableStruct)

// @ts-expect-error
struct3.a = "a"

// $ExpectType Data<{ readonly a: string; }>
// $ExpectType { readonly a: string; }
const struct4 = Data.unsafeStruct(readonlyStruct)

// @ts-expect-error
Expand All @@ -42,7 +42,7 @@ struct4.a = "a"
// tuple
// -------------------------------------------------------------------------------------

// $ExpectType Data<readonly [string, number]>
// $ExpectType readonly [string, number]
const tuple1 = Data.tuple("a", 1)

// @ts-expect-error
Expand All @@ -54,13 +54,13 @@ tuple1[1] = 1
// array
// -------------------------------------------------------------------------------------

// $ExpectType Data<readonly string[]>
// $ExpectType readonly string[]
const array1 = Data.array(mutableArray)

// @ts-expect-error
array1[0] = "a"

// $ExpectType Data<readonly string[]>
// $ExpectType readonly string[]
const array2 = Data.array(readonlyArray)

// @ts-expect-error
Expand All @@ -70,13 +70,13 @@ array2[0] = "a"
// unsafeArray
// -------------------------------------------------------------------------------------

// $ExpectType Data<readonly string[]>
// $ExpectType readonly string[]
const array3 = Data.unsafeArray(mutableArray)

// @ts-expect-error
array3[0] = "a"

// $ExpectType Data<readonly string[]>
// $ExpectType readonly string[]
const array4 = Data.unsafeArray(readonlyArray)

// @ts-expect-error
Expand All @@ -86,7 +86,7 @@ array4[0] = "a"
// case
// -------------------------------------------------------------------------------------

interface Person extends Data.Case {
interface Person {
readonly name: string
}

Expand All @@ -96,13 +96,13 @@ const person = Data.case<Person>()
export type PersonInput = Parameters<typeof person>[0]

// @ts-expect-error
person.name = "a"
person({ name: "" }).name = "a"

// -------------------------------------------------------------------------------------
// tagged
// -------------------------------------------------------------------------------------

interface TaggedPerson extends Data.Case {
interface TaggedPerson {
readonly _tag: "Person"
readonly name: string
readonly optional?: string
Expand All @@ -124,9 +124,9 @@ type HttpError = Data.TaggedEnum<{
BadRequest: { readonly status: 400; readonly a: string }
NotFound: { readonly status: 404; readonly b: number }
}>
// $ExpectType Data<{ readonly _tag: "BadRequest"; readonly status: 400; readonly a: string; }>
// $ExpectType { readonly _tag: "BadRequest"; readonly status: 400; readonly a: string; }
export type BadRequest = Extract<HttpError, { _tag: "BadRequest" }>
// $ExpectType Data<{ readonly _tag: "NotFound"; readonly status: 404; readonly b: number; }>
// $ExpectType { readonly _tag: "NotFound"; readonly status: 404; readonly b: number; }
export type NotFound = Extract<HttpError, { _tag: "NotFound" }>

// @ts-expect-error
Expand All @@ -140,14 +140,14 @@ export type Err = Data.TaggedEnum<{
// -------------------------------------------------------------------------------------

const { NotFound } = Data.taggedEnum<
| Data.Data<{ readonly _tag: "BadRequest"; readonly status: 400; readonly message: string }>
| Data.Data<{ readonly _tag: "NotFound"; readonly status: 404; readonly message: string }>
| { readonly _tag: "BadRequest"; readonly status: 400; readonly message: string }
| { readonly _tag: "NotFound"; readonly status: 404; readonly message: string }
>()

// $ExpectType { readonly status: 404; readonly message: string; }
export type notFoundInput = Parameters<typeof NotFound>[0]

// $ExpectType Data<{ readonly _tag: "NotFound"; readonly status: 404; readonly message: string; }>
// $ExpectType { readonly _tag: "NotFound"; readonly status: 404; readonly message: string; }
export type notFoundOutput = ReturnType<typeof NotFound>

const notFound = NotFound({ status: 404, message: "mesage" })
Expand Down
3 changes: 1 addition & 2 deletions packages/effect/src/Cause.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
*/
import type * as Channel from "./Channel.js"
import type * as Chunk from "./Chunk.js"
import type * as Data from "./Data.js"
import type * as Effect from "./Effect.js"
import type * as Either from "./Either.js"
import type * as Equal from "./Equal.js"
Expand Down Expand Up @@ -190,7 +189,7 @@ export interface CauseReducer<in C, in E, in out Z> {
* @since 2.0.0
* @category models
*/
export interface YieldableError extends Data.Case, Pipeable, Inspectable, Readonly<Error> {
export interface YieldableError extends Pipeable, Inspectable, Readonly<Error> {
readonly [Effect.EffectTypeId]: Effect.Effect.VarianceStruct<never, this, never>
readonly [Stream.StreamTypeId]: Effect.Effect.VarianceStruct<never, this, never>
readonly [Sink.SinkTypeId]: Sink.Sink.VarianceStruct<never, this, unknown, never, never>
Expand Down
Loading

0 comments on commit 02c3461

Please sign in to comment.