Claude-skill-registry effect-foundations
Core Effect foundations and style for a coding agent. Use when starting an Effect task, choosing operators, or structuring a small pipeline.
install
source · Clone the upstream repo
git clone https://github.com/majiayu000/claude-skill-registry
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/effect-foundations" ~/.claude/skills/majiayu000-claude-skill-registry-effect-foundations && rm -rf "$T"
manifest:
skills/data/effect-foundations/SKILL.mdsource content
Effect Foundations & Style
Purpose: Provide a compact, go-to checklist for writing idiomatic Effect TypeScript with data-first pipe style, minimal imperative code, and strong typing. Optimized for a coding agent with limited context.
Triggers
- New Effect implementation or refactor
- Selecting map/flatMap/andThen/tap operators
- Converting promise/callback to Effect
When to use
- You’re unsure which operator to pick (map vs flatMap vs andThen vs tap)
- You need a minimal template for sequential vs parallel code
- You want to keep error and context channels explicit (
)Effect<E, A, R>
Checklist (Do First)
- Prefer data-first
style for readability.pipe() - Use
for sequential logic;Effect.gen
for parallelismEffect.all - Lift values with
, failures withEffect.succeedEffect.fail - Declare errors as
and recover withData.TaggedErrorcatchTag(s) - Keep effects small, composable, and typed—avoid
any - If
(requirements) is notR
, provide layers explicitlynever
Minimal Patterns
- Creation
const value = Effect.succeed(42) const failure = Effect.fail(new MyError())
- Transform
const result = value.pipe( Effect.map((n) => n * 2), Effect.tap((n) => Effect.log(`n=${n}`)) )
- Sequential
const program = Effect.gen(function* () { const a = yield* getA() const b = yield* getB(a) return b })
- Parallel
const both = yield* Effect.all([left(), right()], { concurrency: "unbounded" })
Operator Selection Guide
- Map value:
Effect.map - Chain effect:
Effect.flatMap - Ignore previous result:
Effect.andThen - Side-effect only:
Effect.tap - Provide context:
/layers (see layers skill)Effect.provide - Combine layers:
,Layer.mergeLayer.provide
Key APIs (intuition)
: write sequential code withEffect.gen
for each Effectyield*
: run independent Effects concurrentlyEffect.all(values, { concurrency })
: recover only specific typed errorsEffect.catchTags(...)
: compose dependencies once, reuse everywhereLayer.merge(a, b)
: bridge Effects to async workflowsEffect.runPromise(...)
Real-world snippet: Branching with Match and TaggedError
import { Effect, Match, Data } from "effect" class UnsupportedPlatformError extends Data.TaggedError("UnsupportedPlatformError")<{ readonly platform: string readonly arch: string }>{} const detectPlatform = (rawPlatform: string, rawArch: string) => Effect.gen(function* () { const platform = yield* Match.value(rawPlatform).pipe( Match.when("darwin", () => Effect.succeed("darwin" as const)), Match.when("linux", () => Effect.succeed("linux" as const)), Match.orElse(() => Effect.fail(new UnsupportedPlatformError({ platform: rawPlatform, arch: rawArch }))) ) const arch = yield* Match.value(rawArch).pipe( Match.when("x64", () => Effect.succeed("x64" as const)), Match.when("arm64", () => Effect.succeed("aarch64" as const)), Match.when("aarch64", () => Effect.succeed("aarch64" as const)), Match.orElse(() => Effect.fail(new UnsupportedPlatformError({ platform: rawPlatform, arch: rawArch }))) ) return { platform, arch } })
Recovery (Quick)
program.pipe( Effect.catchTag("DomainError", () => Effect.succeed(fallback)), Effect.catchAll((e) => Effect.fail(new WrappedError({ cause: e }))) )
Tooling Steps (with effect-engineer)
- Grep local examples:
,Effect.gen
,Effect.all.pipe( - Search docs MCP for operator specifics when unsure
- Consult EffectPatterns for canonical idioms (https://github.com/PaulJPhilp/EffectPatterns)
Pitfalls
- Don't mix promises and effects—wrap with
Effect.try/tryPromise - Don't return raw values inside
—alwaysEffect.gen
an Effectyield* - Unsatisfied
requirements → provide layers or adjust architectureR
Local Source Reference
CRITICAL: Search local Effect source before implementing
The full Effect source code is available at
docs/effect-source/. Always search the actual implementation before writing Effect code.
Key Source Files
- Core Effect:
docs/effect-source/effect/src/Effect.ts - Layer:
docs/effect-source/effect/src/Layer.ts - Data:
docs/effect-source/effect/src/Data.ts - Match:
docs/effect-source/effect/src/Match.ts
Example Searches
# Find Effect.gen implementation and patterns grep -rF "Effect.gen" docs/effect-source/effect/src/ # Find all map/flatMap/andThen variants grep -rF "export" docs/effect-source/effect/src/Effect.ts | grep -F "map" grep -rF "export" docs/effect-source/effect/src/Effect.ts | grep -F "flatMap" grep -rF "export" docs/effect-source/effect/src/Effect.ts | grep -F "andThen" # Study error handling patterns grep -rF "catchTag" docs/effect-source/effect/src/ grep -rF "catchAll" docs/effect-source/effect/src/ grep -rF "TaggedError" docs/effect-source/effect/src/ # Find Effect.all concurrency patterns grep -rF "Effect.all" docs/effect-source/effect/src/
Workflow
- Identify the API you need (e.g., Effect.gen, Effect.all)
- Search
for the implementationdocs/effect-source/effect/src/Effect.ts - Study the types, overloads, and patterns
- Look at test files in
for usage examplesdocs/effect-source/effect/test/ - Write your code based on real implementations
Real source code > documentation > assumptions
References
- Agent Skills overview: https://www.anthropic.com/news/skills
- Skills guide: https://docs.claude.com/en/docs/claude-code/skills
- EffectPatterns: https://github.com/PaulJPhilp/EffectPatterns