Back to Skills

ocaml-code-style

verified

OCaml coding style and refactoring patterns. Use when the user asks to tidy, clean up, refactor, or improve OCaml code, reviewing code quality, enforcing naming conventions, or reducing complexity.

View on GitHub

Marketplace

ocaml-claude-marketplace

avsm/ocaml-claude-marketplace

Plugin

ocaml-dev

development

Repository

avsm/ocaml-claude-marketplace
15stars

plugins/ocaml-dev/skills/ocaml-code-style/SKILL.md

Last Verified

January 20, 2026

Install Skill

Select agents to install to:

Scope:
npx add-skill https://github.com/avsm/ocaml-claude-marketplace/blob/main/plugins/ocaml-dev/skills/ocaml-code-style/SKILL.md -a claude-code --skill ocaml-code-style

Installation paths:

Claude
.claude/skills/ocaml-code-style/
Powered by add-skill CLI

Instructions

# OCaml Code Style

## Core Philosophy

1. **Interface-First**: Design `.mli` first. Clean interface > clever implementation.
2. **Modularity**: Small, focused modules. Compose for larger systems.
3. **Simplicity (KISS)**: Clarity over conciseness. Avoid obscure constructs.
4. **Explicitness**: Explicit control flow and error handling. No exceptions for recoverable errors.
5. **Purity**: Prefer pure functions. Isolate side-effects at edges.
6. **NEVER use Obj.magic**: Breaks type safety. Always a better solution.

## Naming Conventions

| Element | Convention | Example |
|---------|------------|---------|
| Files | `lowercase_underscores` | `user_profile.ml` |
| Modules | `Snake_case` | `User_profile` |
| Types | `snake_case`, primary type is `t` | `type user_profile`, `type t` |
| Values | `snake_case` | `find_user`, `create_channel` |
| Variants | `Snake_case` | `Waiting_for_input`, `Processing_data` |

**Function naming**:
- `find_*` returns `option` (may not exist)
- `get_*` returns value directly (must exist)

**Avoid**: Long names with many underscores (`get_user_profile_data_from_database_by_id`).

## Refactoring Patterns

### Option/Result Combinators

```ocaml
(* Before *)
match get_value () with Some x -> Some (x + 1) | None -> None

(* After *)
Option.map (fun x -> x + 1) (get_value ())
```

Prefer: `Option.map`, `Option.bind`, `Option.value`, `Result.map`, `Result.bind`

### Monadic Syntax (let*/let+)

```ocaml
(* Before - nested matches *)
match fetch_user id with
| Ok user -> (match fetch_perms user with Ok p -> Ok (user, p) | Error e -> Error e)
| Error e -> Error e

(* After *)
let open Result.Syntax in
let* user = fetch_user id in
let+ perms = fetch_perms user in
(user, perms)
```

### Pattern Matching Over Conditionals

```ocaml
(* Before *)
if x > 0 then if x < 10 then "small" else "large" else "negative"

(* After *)
match x with
| x when x < 0 -> "negative"
| x when x < 10 -> "small"
| _ -> "large"
```

## Function Design

**Keep functions small

Validation Details

Front Matter
Required Fields
Valid Name Format
Valid Description
Has Sections
Allowed Tools
Instruction Length:
3736 chars