Back to Skills

Data Types

majiayu000
Updated Yesterday
2 views
58
9
58
View on GitHub
Metadesigndata

About

This skill explains Effect's built-in functional data types like Option, Either, and Chunk for handling optional values, errors, and immutable collections. Use it when developers ask about specific types such as `Option.some`, `Either.left`, or `Data.Class` in the Effect framework. It provides practical examples and explanations for working with these type-safe, immutable data structures.

Quick Install

Claude Code

Recommended
Plugin CommandRecommended
/plugin add https://github.com/majiayu000/claude-skill-registry
Git CloneAlternative
git clone https://github.com/majiayu000/claude-skill-registry.git ~/.claude/skills/Data Types

Copy and paste this command in Claude Code to install this skill

Documentation

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

GitHub Repository

majiayu000/claude-skill-registry
Path: skills/data-types

Related Skills

content-collections

Meta

This skill provides a production-tested setup for Content Collections, a TypeScript-first tool that transforms Markdown/MDX files into type-safe data collections with Zod validation. Use it when building blogs, documentation sites, or content-heavy Vite + React applications to ensure type safety and automatic content validation. It covers everything from Vite plugin configuration and MDX compilation to deployment optimization and schema validation.

View skill

creating-opencode-plugins

Meta

This skill provides the structure and API specifications for creating OpenCode plugins that hook into 25+ event types like commands, files, and LSP operations. It offers implementation patterns for JavaScript/TypeScript modules that intercept and extend the AI assistant's lifecycle. Use it when you need to build event-driven plugins for monitoring, custom handling, or extending OpenCode's capabilities.

View skill

langchain

Meta

LangChain is a framework for building LLM applications using agents, chains, and RAG pipelines. It supports multiple LLM providers, offers 500+ integrations, and includes features like tool calling and memory management. Use it for rapid prototyping and deploying production systems like chatbots, autonomous agents, and question-answering services.

View skill

Algorithmic Art Generation

Meta

This skill helps developers create algorithmic art using p5.js, focusing on generative art, computational aesthetics, and interactive visualizations. It automatically activates for topics like "generative art" or "p5.js visualization" and guides you through creating unique algorithms with features like seeded randomness, flow fields, and particle systems. Use it when you need to build reproducible, code-driven artistic patterns.

View skill