Token导航 LogoToken导航

Agent Skill · 研究检索

functional(functional 搜索)

functional 用于查找、检索和筛选相关信息,适合在 Codex、Claude、Cursor、Gemini CLI 中需要根据关键词、任务场景或来源线索快速定位候选结果时使用。可结合来源仓库、安装命令和原始 README 继续核验具体用法。安装前建议确认权限范围、维护状态,以及是否会触发联网、命令执行或文件读写。

functional 是研究检索类 Agent Skill,可用宿主为 Codex、Claude、Cursor、Gemini CLI,通过GitHub 仓库获取,权限为需要联网;许可证信息还不明确,第三方扫描已通过,按安装量在研究检索类的 73,675 个 Skill 里排第 68,654。

总安装 225周安装 9GitHub Stars 633下载 73核验 2026-05-01

安装说明

本站只整理中文说明,不托管安装包,也不代用户安装。
GitHub
许可证
unknown

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:functional(functional 搜索)
来源仓库:https://github.com/citypaul/dotfiles
仓库路径:skills/functional
安装命令:
npx skills add https://github.com/citypaul/dotfiles --skill functional
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。该命令会通过 npx skills 从第三方来源获取 Skill;本站只展示命令,不托管安装包,也不自动执行。

skills.shnpx skills
npx skills add https://github.com/citypaul/dotfiles --skill functional

这个 Skill 是做什么的

研究检索类 Skill 主要解决「找资料、核对事实、把来源整理清楚」的问题,通常会让助手先检索再总结。

functional 用于查找、检索和筛选相关信息,适合在 Codex、Claude、Cursor、Gemini CLI 中根据关键词、任务场景或来源线索快速定位候选结果。它可结合来源仓库、安装命令和原始 README 继续核验具体用法。安装前建议确认权限范围、维护状态,以及是否会触发联网、命令执行或文件读写。

当前顶部介绍已提供,底部简介为空,原始 SKILL.md 摘录缺失。functional 属于研究检索类 Skill,可作为该场景下的辅助能力补充。

来源仓库内路径:skills/functional

上手步骤

4 步
  1. 1

    确认自己的宿主工具

    公开资料标注支持 Codex、Claude、Cursor、Gemini CLI;先确认自己用的是其中之一,再按对应工具的 Skills 目录放置。

  2. 2

    拿到安装命令

    可以直接复制的命令是 npx skills add https://github.com/citypaul/dotfiles --skill functional;命令里的占位符换成自己的路径或密钥再执行。

  3. 3

    安装后重启宿主

    命令执行完要完全退出宿主工具再打开,让新装的 Skill 被重新扫描到,否则列表里可能看不到。

  4. 4

    按最小权限试用

    它需要需要联网,先在测试目录或测试账号里跑,确认没问题再放到正式项目。

常见问题

6 条

functional 怎么安装?

在终端执行 npx skills add https://github.com/citypaul/dotfiles --skill functional。装完完全退出宿主工具再打开,让它重新扫描本地 Skill。

functional 支持哪些 AI 工具?

公开资料标注支持 Codex、Claude、Cursor、Gemini CLI。其他工具只要能读取本地 Skill 目录,一般也能手动放进去,但要自己确认触发方式是否一致。

functional 需要什么权限?

权限级别是需要联网。该 Skill 可能需要联网访问来源站点、仓库或外部 API;具体网络访问范围需要结合源码和 README 复核。

functional 是免费的吗?

公开资料没有标注明确许可证,收费和商用限制都无法确认。正式使用前请到来源仓库核对授权说明。

functional 用的人多吗?

公开数据是累计安装 225 次,近一周安装 9 次,下载 73 次,GitHub 633 星。这些数字来自第三方目录统计,只能当作热度参考,不代表质量或安全性。

functional 安全吗?

第三方扫描结果为通过,但这只覆盖已知的静态检查项,不能替代自己读一遍源码和安装命令。

值得选的地方和要先想清楚的地方

值得选的地方

  • 同时适配 4 种工具,换客户端不用重新找替代品。
  • 第三方扫描已通过,常见的高风险行为没有命中。

先想清楚的地方

  • 许可证没有明确标注,能不能商用、能不能再分发都不确定。
  • 第三方目录整理,版本更新和行为细节以来源仓库为准。

适不适合你

更适合

  • 已经在用 Codex,想直接扩展它能力的人。
  • 需要处理研究检索类任务、又不想每次都手写提示词的人。

不太适合

  • 需要明确授权才能用到公司项目里的场景。
  • 需要厂商级技术支持和 SLA 的生产系统。

研究检索类 Skill 对比

6 个同类
Skill总安装GitHub 星权限许可证扫描
find-skills

寻找技能 · Codex、Claude

31,199,81316,486操作浏览器MIT有提醒
self-improving-agent

自我改进 Agent · OpenClaw

16,464,0023,396接触敏感数据MIT-0通过
soultrace

灵魂追踪 · Codex、Claude

7,588,94412需要联网未明确有提醒
self-improving

自我完善 · OpenClaw

6,829,2841,046需要联网MIT-0通过
microsoft-foundry

微软代工厂 · Codex、Claude

6,614,144764调用外部服务未明确有提醒
functional

functional 搜索 · 本页

225633需要联网未明确通过

按安装量取同分类前几名;数字来自第三方目录统计,只作热度参考,不代表质量结论。

SKILL.md 原文

Functional Patterns

Core Principles

  • No data mutation - immutable structures only
  • Pure functions wherever possible
  • Composition over inheritance
  • No comments - code should be self-documenting
  • Array methods over loops
  • Options objects over positional parameters

Why Immutability Matters

Immutable data is the foundation of functional programming. Understanding WHY helps you embrace it:

  • Predictable: Same input always produces same output (no hidden state changes)
  • Debuggable: State doesn't change unexpectedly - easier to trace bugs
  • Testable: No hidden mutable state makes tests straightforward
  • React-friendly: React's reconciliation and memoization optimizations work correctly
  • Concurrency-safe: No race conditions when data can't change

Example of the problem:

// ❌ WRONG - Mutation creates unpredictable behavior
const user = { name: 'Alice', permissions: ['read'] };
grantPermission(user, 'write'); // Mutates user.permissions internally
console.log(user.permissions); // ['read', 'write'] - SURPRISE! user changed
// ✅ CORRECT - Immutable approach is predictable
const user = { name: 'Alice', permissions: ['read'] };
const updatedUser = grantPermission(user, 'write'); // Returns new object
console.log(user.permissions); // ['read'] - original unchanged
console.log(updatedUser.permissions); // ['read', 'write'] - new version

Functional Light

We follow "Functional Light" principles - practical functional patterns without heavy abstractions:

What we DO:

  • Pure functions and immutable data
  • Composition and declarative code
  • Array methods over loops
  • Type safety and readonly

What we DON'T do:

  • Category theory or monads
  • Heavy FP libraries (fp-ts, Ramda)
  • Over-engineering with abstractions
  • Functional for the sake of functional

Why: The goal is maintainable, testable code - not academic purity. If a functional pattern makes code harder to understand, don't use it.

Example - Keep it simple:

// ✅ GOOD - Simple, clear, functional
const activeUsers = users.filter(u => u.active);
const userNames = activeUsers.map(u => u.name);

// ❌ OVER-ENGINEERED - Unnecessary abstraction
const compose = <T>(...fns: Array<(arg: T) => T>) => (x: T) =>
  fns.reduceRight((v, f) => f(v), x);
const activeUsers = compose(
  filter((u: User) => u.active),
  map((u: User) => u.name)
)(users);

No Comments / Self-Documenting Code

Code should be clear through naming and structure. Comments indicate unclear code.

Exception: JSDoc for public APIs when generating documentation.

Examples

❌ WRONG - Comments explaining unclear code

// Get the user and check if active and has permission
function check(u: any) {
  // Check user exists
  if (u) {
    // Check if active
    if (u.a) {
      // Check permission
      if (u.p) {
        return true;
      }
    }
  }
  return false;
}

✅ CORRECT - Self-documenting code

function canUserAccessResource(user: User | undefined): boolean {
  if (!user) return false;
  if (!user.isActive) return false;
  if (!user.hasPermission) return false;
  return true;
}

// Even better - compose predicates
function canUserAccessResource(user: User | undefined): boolean {
  return user?.isActive && user?.hasPermission;
}

When Code Needs Explaining

If code requires comments to understand, refactor instead:

  • Extract functions with descriptive names
  • Use meaningful variable names
  • Break complex logic into steps
  • Use type aliases for domain concepts

✅ Acceptable JSDoc for public APIs

/**
 * Registers a scenario for runtime switching.
 * @param definition - The scenario configuration including mocks and metadata
 * @throws {ValidationError} if scenario ID is duplicate
 */
export function registerScenario(definition: ScenaristScenario): void {
  // Implementation
}

Array Methods Over Loops

Prefer map, filter, reduce for transformations. They're declarative (what, not how) and naturally immutable.

Map - Transform Each Element

❌ WRONG - Imperative loop

const scenarioIds = [];
for (const scenario of scenarios) {
  scenarioIds.push(scenario.id);
}

✅ CORRECT - Functional map

const scenarioIds = scenarios.map(s => s.id);

Filter - Select Subset

❌ WRONG - Imperative loop

const activeScenarios = [];
for (const scenario of scenarios) {
  if (scenario.active) {
    activeScenarios.push(scenario);
  }
}

✅ CORRECT - Functional filter

const activeScenarios = scenarios.filter(s => s.active);

Reduce - Aggregate Values

❌ WRONG - Imperative loop

let total = 0;
for (const item of items) {
  total += item.price * item.quantity;
}

✅ CORRECT - Functional reduce

const total = items.reduce((sum, item) => sum + item.price * item.quantity, 0);

Chaining Multiple Operations

✅ CORRECT - Compose array methods

const total = items
  .filter(item => item.active)
  .map(item => item.price * item.quantity)
  .reduce((sum, price) => sum + price, 0);

When Loops Are Acceptable

Imperative loops are fine when:

  • Early termination is essential (use for...of with break)
  • Performance critical (measure first!)
  • Side effects are necessary (logging, DOM manipulation)

But even then, consider:

  • Array.find() for early termination
  • Array.some() / Array.every() for boolean checks

Options Objects Over Positional Parameters

Default to options objects for function parameters. This improves readability and reduces ordering dependencies.

Why Options Objects?

Benefits:

  • Named parameters (clear what each argument means)
  • No ordering dependencies
  • Easy to add optional parameters
  • Self-documenting at call site
  • TypeScript autocomplete

Examples

❌ WRONG - Positional parameters

function createPayment(
  amount: number,
  currency: string,
  cardId: string,
  cvv: string,
  saveCard: boolean,
  sendReceipt: boolean
): Payment {
  // ...
}

// Call site - unclear what parameters mean
createPayment(100, 'GBP', 'card_123', '123', true, false);

✅ CORRECT - Options object

type CreatePaymentOptions = {
  amount: number;
  currency: string;
  cardId: string;
  cvv: string;
  saveCard?: boolean;
  sendReceipt?: boolean;
};

function createPayment(options: CreatePaymentOptions): Payment {
  const { amount, currency, cardId, cvv, saveCard = false, sendReceipt = true } = options;
  // ...
}

// Call site - crystal clear
createPayment({
  amount: 100,
  currency: 'GBP',
  cardId: 'card_123',
  cvv: '123',
  saveCard: true,
});

When Positional Parameters Are OK

Use positional parameters when:

  • 1-2 parameters max
  • Order is obvious (e.g., add(a, b))
  • High-frequency utility functions
// ✅ OK - Obvious ordering, few parameters
function add(a: number, b: number): number {
  return a + b;
}

function updateUser(user: User, changes: Partial<User>): User {
  return { ...user, ...changes };
}

Pure Functions

Pure functions have no side effects and always return the same output for the same input.

What Makes a Function Pure?

  1. No side effects

- Doesn't mutate external state - Doesn't modify function arguments - Doesn't perform I/O (network, file system, console)

  1. Deterministic

- Same input → same output - No dependency on external state (Date.now(), Math.random(), global vars)

  1. Referentially transparent

- Can replace function call with its return value

Examples

❌ WRONG - Impure function (mutations)

function addScenario(scenarios: Scenario[], newScenario: Scenario): void {
  scenarios.push(newScenario); // ❌ Mutates input
}

let count = 0;
function increment(): number {
  count++; // ❌ Modifies external state
  return count;
}

✅ CORRECT - Pure functions

function addScenario(
  scenarios: ReadonlyArray<Scenario>,
  newScenario: Scenario,
): ReadonlyArray<Scenario> {
  return [...scenarios, newScenario]; // ✅ Returns new array
}

function increment(count: number): number {
  return count + 1; // ✅ No external state
}

Benefits of Pure Functions

  • Testable: No setup/teardown needed
  • Composable: Easy to combine
  • Predictable: No hidden behavior
  • Cacheable: Memoization possible
  • Parallelizable: No race conditions

When Impurity Is Necessary

Some functions must be impure (I/O, randomness, side effects). Isolate them:

// ✅ CORRECT - Isolate impure functions at edges
// Pure core
function calculateTotal(items: ReadonlyArray<Item>): number {
  return items.reduce((sum, item) => sum + item.price, 0);
}

// Impure shell (isolated)
async function saveOrder(order: Order): Promise<void> {
  const total = calculateTotal(order.items); // Pure
  await database.save({ ...order, total }); // Impure (I/O)
}

Pattern: Keep impure functions at system boundaries (adapters, ports). Keep core domain logic pure.


Composition Over Complex Logic

Compose small functions into larger ones. Each function does one thing well.

Benefits of Composition

  • Easier to understand (each piece is simple)
  • Easier to test (test pieces independently)
  • Easier to reuse (pieces work in multiple contexts)
  • Easier to maintain (change one piece without affecting others)

Examples

❌ WRONG - Complex monolithic function

function registerScenario(input: unknown) {
  if (typeof input !== 'object' || !input) {
    throw new Error('Invalid input');
  }
  if (!('id' in input) || typeof input.id !== 'string') {
    throw new Error('Missing id');
  }
  if (!('name' in input) || typeof input.name !== 'string') {
    throw new Error('Missing name');
  }
  if (!('mocks' in input) || !Array.isArray(input.mocks)) {
    throw new Error('Missing mocks');
  }
  // ... 50 more lines of validation and registration
}

✅ CORRECT - Composed functions

// Small, focused functions
const validate = (input: unknown) => ScenarioSchema.parse(input);
const register = (scenario: Scenario) => registry.register(scenario);

// Compose them
const registerScenario = (input: unknown) => register(validate(input));

// Even better - use pipe/compose utilities
const registerScenario = pipe(
  validate,
  register,
);

Composing Immutable Transformations

// Small transformation functions
const addDiscount = (order: Order, percent: number): Order => ({
  ...order,
  total: order.total * (1 - percent / 100),
});

const addShipping = (order: Order, cost: number): Order => ({
  ...order,
  total: order.total + cost,
});

const addTax = (order: Order, rate: number): Order => ({
  ...order,
  total: order.total * (1 + rate),
});

// Compose them
const finalizeOrder = (order: Order): Order => {
  return addTax(
    addShipping(
      addDiscount(order, 10),
      5.99
    ),
    0.2
  );
};

// Or use pipe for left-to-right reading
const finalizeOrder = (order: Order): Order =>
  pipe(
    order,
    o => addDiscount(o, 10),
    o => addShipping(o, 5.99),
    o => addTax(o, 0.2),
  );

Readonly Keyword for Immutability

Use readonly on all data structures to signal immutability intent.

readonly on Properties

// ✅ CORRECT - Immutable data structure
type Scenario = {
  readonly id: string;
  readonly name: string;
  readonly description: string;
};

// ❌ WRONG - Mutable
type Scenario = {
  id: string;
  name: string;
};

ReadonlyArray vs Array

// ✅ CORRECT - Immutable array
type Scenario = {
  readonly mocks: ReadonlyArray<Mock>;
};

// ❌ WRONG - Mutable array
type Scenario = {
  readonly mocks: Mock[];
};

Nested readonly

// ✅ CORRECT - Deep immutability
type Mock = {
  readonly method: 'GET' | 'POST';
  readonly response: {
    readonly status: number;
    readonly body: readonly unknown[];
  };
};

Why readonly Matters

  • Compiler enforces immutability: TypeScript errors on mutation attempts
  • Self-documenting: Signals "don't mutate this"
  • Functional programming alignment: Natural fit for FP patterns
  • Prevents accidental bugs: Can't accidentally mutate data

Deep Nesting Limitation

Max 2 levels of function nesting. Beyond that, extract functions.

Why Limit Nesting?

  • Deeply nested code is hard to read
  • Hard to test (many paths through code)
  • Hard to modify (tight coupling)
  • Sign of missing abstractions

Examples

❌ WRONG - Deep nesting (4+ levels)

function processOrder(order: Order) {
  if (order.items.length > 0) {
    if (order.customer.verified) {
      if (order.total > 0) {
        if (order.payment.valid) {
          // ... deeply nested logic
        }
      }
    }
  }
}

✅ CORRECT - Flat with early returns

function processOrder(order: Order) {
  if (order.items.length === 0) return;
  if (!order.customer.verified) return;
  if (order.total <= 0) return;
  if (!order.payment.valid) return;

  // Main logic at top level
}

✅ CORRECT - Extract to functions

function processOrder(order: Order) {
  if (!canProcessOrder(order)) return;
  const validated = validateOrder(order);
  return executeOrder(validated);
}

function canProcessOrder(order: Order): boolean {
  return order.items.length > 0
    && order.customer.verified
    && order.total > 0
    && order.payment.valid;
}

Immutable Array Operations

Complete catalog of array mutations and their immutable alternatives:

// ❌ WRONG - Mutations
items.push(newItem);        // Add to end
items.pop();                // Remove last
items.unshift(newItem);     // Add to start
items.shift();              // Remove first
items.splice(index, 1);     // Remove at index
items.reverse();            // Reverse order
items.sort();               // Sort
items[i] = newValue;        // Update at index

// ✅ CORRECT - Immutable alternatives
const withNew = [...items, newItem];           // Add to end
const withoutLast = items.slice(0, -1);        // Remove last
const withFirst = [newItem, ...items];         // Add to start
const withoutFirst = items.slice(1);           // Remove first
const removed = [...items.slice(0, index),     // Remove at index
                 ...items.slice(index + 1)];
const reversed = [...items].reverse();         // Reverse (copy first!)
const sorted = [...items].sort();              // Sort (copy first!)
const updated = items.map((item, idx) =>       // Update at index
  idx === i ? newValue : item
);

Common patterns:

// Filter out specific item
const withoutItem = items.filter(item => item.id !== targetId);

// Replace specific item
const replaced = items.map(item =>
  item.id === targetId ? newItem : item
);

// Insert at specific position
const inserted = [
  ...items.slice(0, index),
  newItem,
  ...items.slice(index)
];

Immutable Object Updates

// ❌ WRONG
user.name = "New";
Object.assign(user, { name: "New" });

// ✅ CORRECT
const updated = { ...user, name: "New" };

Nested Updates

// ✅ CORRECT - Immutable nested update
const updatedCart = {
  ...cart,
  items: cart.items.map((item, i) =>
    i === targetIndex ? { ...item, quantity: newQuantity } : item
  ),
};

// ✅ CORRECT - Immutable nested array update
const updatedOrder = {
  ...order,
  items: [
    ...order.items.slice(0, index),
    updatedItem,
    ...order.items.slice(index + 1),
  ],
};

Early Returns Over Nesting

// ❌ WRONG - Nested conditions
if (user) {
  if (user.isActive) {
    if (user.hasPermission) {
      // do something
    }
  }
}

// ✅ CORRECT - Early returns (guard clauses)
if (!user) return;
if (!user.isActive) return;
if (!user.hasPermission) return;

// do something

Result Type for Error Handling

type Result<T, E = Error> =
  | { readonly success: true; readonly data: T }
  | { readonly success: false; readonly error: E };

// Usage
function processPayment(payment: Payment): Result<Transaction> {
  if (payment.amount <= 0) {
    return { success: false, error: new Error('Invalid amount') };
  }

  const transaction = executePayment(payment);
  return { success: true, data: transaction };
}

// Caller handles both cases explicitly
const result = processPayment(payment);
if (!result.success) {
  console.error(result.error);
  return;
}

// TypeScript knows result.data exists here
console.log(result.data.transactionId);

Summary Checklist

When writing functional code, verify:

  • No data mutation - using spread operators
  • Pure functions wherever possible (no side effects)
  • Code is self-documenting (no comments needed)
  • Array methods (map, filter, reduce) over loops
  • Options objects for 3+ parameters
  • Composed small functions, not complex monoliths
  • readonly on all data structure properties
  • ReadonlyArray<T> for immutable arrays
  • Max 2 levels of nesting (use early returns)
  • Result types for error handling

平台分布

Codex

33.88%
按下载量换算25

Claude

28.64%
按下载量换算21

Cursor

18.69%
按下载量换算14

Gemini CLI

9.42%
按下载量换算7

安全审计

Gen Agent Trust Hub

通过

Socket

通过

Snyk

通过

权限和风险

需要联网

该 Skill 可能需要联网访问来源站点、仓库或外部 API;具体网络访问范围需要结合源码和 README 复核。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。目前只有一个公开来源,建议同时核对源仓库。

继续浏览同类 Skills