mcpField
F
fp-ts-pragmatic

fp-ts-pragmatic

github.com/sickn33开发48.7k88 次安装今天更新
代码仓库

关于 fp-ts-pragmatic

面向 TypeScript 开发者的 fp-ts 实用指南,聚焦可空值、错误和异步操作的函数式模式,并说明何时应采用更简单的写法。

主要功能

  1. 01处理可空值的实用模式
  2. 02组织错误处理
  3. 03处理异步操作
  4. 04将命令式代码改为函数式风格
  5. 05说明不宜使用函数式编程的场景

适用场景

  1. 01为 fp-ts 入门寻找实践指引
  2. 02整理 TypeScript 错误处理
  3. 03重构异步逻辑
  4. 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