AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
SKILL verified MIT Self-run

Data Types

skill-andrueandersoncs-claude-skill-effect-ts-data-types · by andrueandersoncs

This skill should be used when the user asks about "Effect Option", "Effect Either", "Option.some", "Option.none", "Either.left", "Either.right", "Cause", "Exit", "Chunk", "Data", "Data.TaggedEnum", "Data.Class", "Duration", "DateTime", "HashMap", "HashSet", "Redacted", or needs to understand Effect's built-in data types and functional data structures.

No reviews yet
0 installs
35 views
0.0% view→install

Install

$ agentstack add skill-andrueandersoncs-claude-skill-effect-ts-data-types

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/skill-andrueandersoncs-claude-skill-effect-ts-data-types)

Reliability & compatibility

Security review passed
0 installs to date
no reviews yet
6mo ago

Declared compatibility

Claude CodeClaude Desktop

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Data Types? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

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()),
  );
});

Option Chaining - flatMap over Nested match

NEVER nest Option.match calls. When chaining multiple optional operations that share the same fallback, use Option.flatMap with a single Option.getOrElse:

// ❌ FORBIDDEN: Nested Option.match (pyramid of doom)
// Every onNone returns the same default — this is the signal to use flatMap
const result = pipe(
  users,
  Array.findFirst((u) => u.role === "admin"),
  Option.match({
    onNone: () => defaultName,
    onSome: (admin) =>
      Option.match(admin.department, {
        onNone: () => defaultName,
        onSome: (dept) =>
          pipe(
            departments,
            Array.findFirst((d) => d.id === dept),
            Option.match({
              onNone: () => defaultName,
              onSome: (d) => d.name,
            }),
          ),
      }),
  }),
);

// ✅ REQUIRED: Option.flatMap chain with single getOrElse
const result = pipe(
  users,
  Array.findFirst((u) => u.role === "admin"),
  Option.flatMap((admin) => admin.department),
  Option.flatMap((dept) =>
    pipe(
      departments,
      Array.findFirst((d) => d.id === dept),
    ),
  ),
  Option.map((d) => d.name),
  Option.getOrElse(() => defaultName),
);

When to use which:

| Pattern | Use When | | ---------------------- | ---------------------------------------------------------------- | | Option.match | Converting Option to a different type (single use) | | Option.flatMap chain | Chaining multiple optional operations with same fallback | | Option.map | Transforming the inner value without changing Option wrapper | | Option.getOrElse | Extracting the value with a default at the end of a chain | | Option.filter | Adding a condition that may turn Some into None |

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 {}

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", { userId: Schema.String }) {}

// Tagged enum
type Shape = Data.TaggedEnum;
const { Circle, Rectangle } = Data.taggedEnum();

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();

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

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.