关于 fp-ts-pragmatic
面向 TypeScript 开发者的 fp-ts 实用指南,聚焦可空值、错误和异步操作的函数式模式,并说明何时应采用更简单的写法。
主要功能
- 01处理可空值的实用模式
- 02组织错误处理
- 03处理异步操作
- 04将命令式代码改为函数式风格
- 05说明不宜使用函数式编程的场景
适用场景
- 01为 fp-ts 入门寻找实践指引
- 02整理 TypeScript 错误处理
- 03重构异步逻辑
- 04评估简单代码是否需要函数式抽象
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ sickn33/ agentic-awesome-skills --skill fp-ts-pragmatic安装后在 Claude Code 中输入/fp-ts-pragmatic确认已加载。
附带文件references/detailed-guide.md
详细介绍
务实函数式编程
请先阅读本文。 本指南摒弃学术术语,直接告诉你真正重要的内容。没有范畴论,没有抽象的空谈。只有能让你的代码变得更好的模式。
详细指南
在执行本技能之前,请阅读详细指南。其中保留了完整的流程和参考资料。请将其中的安全要求、前置条件和验证要求视为强制性的。对于聚焦的工作,加载相关章节;对于端到端的工作,请完整阅读该指南。
何时使用本技能
- 当你刚开始使用 fp-ts 并需要实用指导时
- 当你编写处理可空值、错误或异步操作的 TypeScript 代码时
- 当你想要更简洁、更易维护的函数式代码,而不想承受学术负担时
- 当你要将命令式代码重构为函数式风格时
何时不要使用函数式编程
函数式编程并不总是正确答案。以下情况应保持简单。
简单的空值检查
// Just use optional chaining - it's built into the language
const city = user?.address?.city ?? 'Unknown'
// DON'T overcomplicate it
const city = pipe(
O.fromNullable(user),
O.flatMap(u => O.fromNullable(u.address)),
O.flatMap(a => O.fromNullable(a.city)),
O.getOrElse(() => 'Unknown')
)
简单的循环
// A for loop is fine when you need early exit or complex logic
function findFirst(items: Item[], predicate: (i: Item) => boolean): Item | null {
for (const item of items) {
if (predicate(item)) return item
}
return null
}
// DON'T force FP when it doesn't help
const result = pipe(
items,
A.findFirst(predicate),
O.toNullable
)
性能关键的代码
// For hot paths, benchmark both implementations on the actual runtime
function sumLarge(numbers: number[]): number {
let sum = 0
for (let i = 0; i < numbers.length; i++) {
sum += numbers[i]
}
return sum
}
// A.reduce does not create an intermediate array per item; callbacks still have runtime costs
const sum = pipe(numbers, A.reduce(0, (acc, n) => acc + n))
当你的团队不了解函数式编程时
如果只有你能读懂这段代码,那它就不是好代码。
// If your team knows this pattern
async function getUser(id: string): Promise<User | null> {
try {
const response = await fetch(`/api/users/${encodeURIComponent(id)}`)
if (!response.ok) return null
return await response.json()
} catch {
return null
}
}
// Don't force this on them
const getUser = (id: string): TE.TaskEither<Error, User> =>
pipe(
TE.tryCatch(() => fetch(`/api/users/${encodeURIComponent(id)}`), E.toError),
TE.flatMap(r => r.ok ? TE.right(r) : TE.left(new Error('Not found'))),
TE.flatMap(r => TE.tryCatch(() => r.json(), E.toError))
)
限制
- 仅在任务明确符合上述范围时使用本技能。
- 不要将输出视为针对特定环境的验证、测试或专家评审的替代品。
- 如果缺少必需的输入、权限、安全边界或成功标准,请停止并请求澄清。
评论
支持 Markdown