data types

📁 andrueandersoncs/claude-skill-effect-ts 📅 Jan 1, 1970
8
总安装量
0
周安装量
#34720
全站排名
安装命令
npx skills add https://github.com/andrueandersoncs/claude-skill-effect-ts --skill Data Types

Skill 文档

Data Types in Effect

Overview

Effect provides immutable, type-safe data structures:

  • Option – Represents optional values (Some/None)
  • Either – Represents success/failure (Right/Left)
  • Cause – Detailed failure information
  • Exit – Effect execution result
  • Data – Value equality for classes
  • Chunk – Immutable indexed sequence
  • Duration – Time spans
  • DateTime – Date/time handling

Option

Represents a value that may or may not exist:

import { Option } from "effect"

const some = Option.some(42)
const none = Option.none()

const fromNull = Option.fromNullable(maybeNull)

const result = Option.match(option, {
  onNone: () => "No value",
  onSome: (value) => `Got: ${value}`
})

const value = Option.getOrElse(option, () => defaultValue)

const doubled = Option.map(option, (n) => n * 2)

const chained = Option.flatMap(option, (n) =>
  n > 0 ? Option.some(n) : Option.none()
)

const positive = Option.filter(option, (n) => n > 0)

Option with Effect

const program = Effect.gen(function* () {
  const maybeUser = yield* findUser(id)

  // Convert Option to Effect
  const user = yield* Option.match(maybeUser, {
    onNone: () => Effect.fail(new UserNotFound()),
    onSome: Effect.succeed
  })

  // Or use Effect.fromOption
  const user = yield* maybeUser.pipe(
    Effect.fromOption,
    Effect.mapError(() => new UserNotFound())
  )
})

Either

Represents a value that is either Left (failure) or Right (success):

import { Either } from "effect"

const right = Either.right(42)
const left = Either.left("error")

const result = Either.match(either, {
  onLeft: (error) => `Error: ${error}`,
  onRight: (value) => `Success: ${value}`
})

const doubled = Either.map(either, (n) => n * 2)

const mapped = Either.mapLeft(either, (e) => new Error(e))

const both = Either.mapBoth(either, {
  onLeft: (e) => new Error(e),
  onRight: (n) => n * 2
})

const chained = Either.flatMap(either, (n) =>
  n > 0 ? Either.right(n) : Either.left("negative")
)

const value = Either.getOrThrow(either)

Cause

Complete failure information for an Effect:

import { Cause } from "effect"

Cause.fail(error)
Cause.die(defect)
Cause.interrupt(id)
Cause.empty
Cause.sequential(c1, c2)
Cause.parallel(c1, c2)

Cause.isFailure(cause)
Cause.isDie(cause)
Cause.isInterrupt(cause)

const failures = Cause.failures(cause)
const defects = Cause.defects(cause)

const message = Cause.pretty(cause)

Exit

The result of running an Effect:

import { Exit } from "effect"

Exit.succeed(value)
Exit.fail(cause)

const result = Exit.match(exit, {
  onFailure: (cause) => `Failed: ${Cause.pretty(cause)}`,
  onSuccess: (value) => `Succeeded: ${value}`
})

Exit.isSuccess(exit)
Exit.isFailure(exit)

const value = Exit.getOrElse(exit, () => defaultValue)

const mapped = Exit.map(exit, (a) => a * 2)

Data – Value Equality

Create classes with structural equality:

import { Data, Schema } from "effect"

// Tagged class
class Person extends Data.Class<{
  readonly name: string
  readonly age: number
}> {}

const alice1 = new Person({ name: "Alice", age: 30 })
const alice2 = new Person({ name: "Alice", age: 30 })

alice1 === alice2  // false (reference)
Equal.equals(alice1, alice2)  // true (structural)

// Tagged errors (used with Effect.fail)
// Use Schema.TaggedError for domain errors - works with Schema.is(), catchTag, and Match.tag
class UserNotFound extends Schema.TaggedError<UserNotFound>()(
  "UserNotFound",
  { userId: Schema.String }
) {}

// Tagged enum
type Shape = Data.TaggedEnum<{
  Circle: { radius: number }
  Rectangle: { width: number; height: number }
}>
const { Circle, Rectangle } = Data.taggedEnum<Shape>()

const circle = Circle({ radius: 10 })
const rect = Rectangle({ width: 5, height: 3 })

Chunk

Immutable indexed sequence optimized for Effect:

import { Chunk } from "effect"

const chunk = Chunk.make(1, 2, 3, 4, 5)
const fromArray = Chunk.fromIterable([1, 2, 3])
const empty = Chunk.empty<number>()

const head = Chunk.head(chunk)
const tail = Chunk.tail(chunk)
const take = Chunk.take(chunk, 2)
const drop = Chunk.drop(chunk, 2)

const doubled = Chunk.map(chunk, (n) => n * 2)
const filtered = Chunk.filter(chunk, (n) => n > 2)
const sum = Chunk.reduce(chunk, 0, (acc, n) => acc + n)

const array = Chunk.toArray(chunk)
const readonlyArray = Chunk.toReadonlyArray(chunk)

Duration

Represent time spans:

import { Duration } from "effect"

const ms = Duration.millis(100)
const secs = Duration.seconds(5)
const mins = Duration.minutes(10)
const hours = Duration.hours(2)
const days = Duration.days(1)

const fromString = Duration.decode("5 seconds")

const total = Duration.sum(duration1, duration2)
const remaining = Duration.subtract(total, elapsed)

Duration.greaterThan(a, b)
Duration.lessThanOrEqualTo(a, b)

const milliseconds = Duration.toMillis(duration)
const seconds = Duration.toSeconds(duration)

DateTime

Date and time handling:

import { DateTime } from "effect"

const now = DateTime.now

const fromDate = DateTime.fromDate(new Date())

const specific = DateTime.make({
  year: 2024,
  month: 1,
  day: 15,
  hours: 10,
  minutes: 30
})

const tomorrow = DateTime.add(now, { days: 1 })
const lastWeek = DateTime.subtract(now, { weeks: 1 })

const formatted = DateTime.format(now, "yyyy-MM-dd")

const utc = DateTime.setZone(now, "UTC")
const local = DateTime.setZone(now, DateTime.zoneLocal)

HashMap & HashSet

Immutable hash-based collections:

import { HashMap, HashSet } from "effect"

const map = HashMap.make(
  ["a", 1],
  ["b", 2],
  ["c", 3]
)

const value = HashMap.get(map, "a")
const updated = HashMap.set(map, "d", 4)
const removed = HashMap.remove(map, "a")

const set = HashSet.make(1, 2, 3, 4, 5)

const has = HashSet.has(set, 3)
const added = HashSet.add(set, 6)
const removed = HashSet.remove(set, 1)
const union = HashSet.union(set1, set2)
const intersection = HashSet.intersection(set1, set2)

Redacted

Protect sensitive values from logging:

import { Redacted } from "effect"

const apiKey = Redacted.make("sk-secret-key-123")

console.log(apiKey)
console.log(`Key: ${apiKey}`)

const actual = Redacted.value(apiKey)

Best Practices

  1. Use Option for nullable values – Explicit handling required
  2. Use Either for validation – Accumulate errors
  3. Use Schema.TaggedError for Effect errors – Enables catchTag and Schema.is()
  4. Use Chunk in streaming – Optimized for Effect operations
  5. Use Redacted for secrets – Prevents accidental exposure
  6. Use Duration for time – Type-safe time operations

Additional Resources

For comprehensive data type documentation, consult ${CLAUDE_PLUGIN_ROOT}/references/llms-full.txt.

Search for these sections:

  • “Option” for optional values
  • “Either” for success/failure
  • “Cause” for error details
  • “Exit” for execution results
  • “Data” for value equality
  • “Chunk” for sequences
  • “DateTime” for date handling