ocaml について
OCaml を学ぶ開発者向けのスキルで、言語の慣用表現とその理由を解説します。型推論、実行時モデル、プロジェクト構成、テスト、アルゴリズムを扱います。
主な機能
- 01型推論とコンパイラーエラーの解説
- 02パターンマッチと関数型の慣用表現
- 03実行時モデル、等価性、可変値
- 04Dune プロジェクトと Alcotest テスト
- 05データ構造とアルゴリズムの指針
活用シーン
- 01JS、TS、PHP から OCaml への移行
- 02型推論エラーやコンパイラーメッセージの理解
- 03Dune プロジェクトとテストの作成
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ bsene/ skills --skill ocamlインストール後、Claude Code で/ocamlを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/benchmarks.mdcore-language-cheat-sheet.mddata-structures-and-algorithms.mddune-and-alcotest.mdinference-and-compiler-errors.mdlearn-programming-with-ocaml.mdlearning-resources.mdrepresentation-and-invariants.mdruntime-model.mdtesting-and-quality.md詳細
OCaml
OCaml は静的型付けの、主に関数型の言語で、強力な型推論エンジン(Hindley-Milner)を備えています。JS/TS/PHP から移行する際に最も大きく変わるのは構文ではありません。コンパイラーはリンターではなく、設計のパートナーです。網羅的なパターンマッチと健全な型システムによって、実行時に検出する、あるいはまったく検出できないことに慣れているバグ(null チェックやケースの見落としなど)を、コンパイル時にその種類ごと捕捉できます。
何かが慣用的であることだけでなく、_なぜ_慣用的なのかを説明することを基本としてください。ユーザーは構文を翻訳するだけでなく、言語を学んでいます。
型推論:求められない限り注釈を付けない
OCaml はほぼ常に正しく型を推論します。ユーザーから注釈を求められた場合(または .mli で必要な場合)を除き、次のように、型注釈なしで束縛や関数を記述してください。let total_ttc price_ht tax_rate = price_ht *. (1. +. tax_rate)。推論された型を確認するには、ocamlc -i file.ml、dune utop、またはトップレベルを使います。型推論エラーを読む際は、制約を順にたどってください。報告されたエラーは、満たせない制約のうち最後のものであり、必ずしも間違いが生じた箇所とは限りません。例と詳しい方法については、型推論とコンパイラーエラーを参照してください。
言語の基本事項
letは不変です。変更には明示的なrefが必要です。まずは再束縛や再帰を優先してください。matchは網羅性がチェックされます。バリアントは TS のユニオン型/列挙型、レコードはオブジェクトインターフェイス、optionは null、resultは制御フローとしての例外に代わるものです。- 例外は型システムで追跡されません。想定される失敗には、
option/resultを基本的に使ってください。 - すべての関数はカリー化されています。
|>はパイプ演算子です。再帰にはrecが必要です。アキュムレーターを使うラッパーによる末尾再帰を優先し、ループ内でacc @ [x]を使うのは避けてください。 =は構造的等価性、==は物理的同一性を比較します。JS 開発者の直感とは逆で、ほとんどの場合は=が適切です。intは 63 ビットで、オーバーフローしても暗黙にラップします。intとfloatは混在できません(+.、-.、*.、/.)。- モジュールと
.mliシグネチャが、インターフェイスとプライバシーを実現する仕組みです。クラスより、モジュール+レコード+関数を優先してください。 - 引数の評価順序は未規定です。順序を固定するには
let ... inを使ってください。
例を含む完全なチートシート(畳み込み、; による逐次実行、例外、カリー化、末尾再帰)については、言語の基本チートシートを参照してください。
ランタイムモデル(等価性や変更について説明する際に使用)
= と == の違い、変更、または「なぜこうなっているのか」に関する回答は、必ずこのモデルに基づいて明示してください。これは任意の背景知識ではありません。
- OCaml の値は、ボックス化されていない整数か、ヒープ上のブロックへのポインター(ヘッダーワード+N 個の値ワード)のいずれかです。
- タプル、配列、レコード、定数ではないバリアントコンストラクターは、すべて単なるブロックです。
{ x = 1.; y = 2. }は 2 ワードのブロックへのポインターなので、フィールドが同一の 2 つのレコードも、それぞれ別個に確保されたブロックです。 refは 1 つのフィールドを持つ変更可能なレコード、listは 2 ワードの::セルの連鎖、クロージャはコードポインターとキャプチャした環境を持つブロックです。そのため、ref/:=/!は独立した言語機能ではなく、ほかのあらゆるものと組み合わせられます。- 等価性への影響:
==は 2 つのワードだけを比較します(循環値でも定数時間です)。=はブロックの内部までたどるため、循環があると無限ループになることがあります。
詳しい解説については、references/runtime-model.mdを参照してください。
プロジェクト構成とテスト
- 新しいプロジェクトを作成するには
dune init proj <name>を実行し(必要に応じてopam exec --を前置します)、その後dune build @checkと通常のdune buildで検証します。dune buildはコンパイル、dune runtestはテストの実行、dune exec ./foo.exeは実行ファイルの実行に使います。生成された.opamを手動で編集してはいけません。dune-projectを編集してください。 - 単体テストには Alcotest を使います。実際のプロジェクトでは、プロパティベーステスト(qcheck)とミューテーションテスト(mutaml)を追加します。セットアップ、スタンザ、Alcotest の形式については、dune と Alcotestを参照してください。テスト種別の選択については、テストと品質を参照してください。
デバッグ
dune build の出力を事実として扱ってください。型エラーは通常、実際のロジック上の欠落を示しています。標準的なメッセージ、警告(8、10、11)、コアの型付け規則については、型推論とコンパイラーエラーを参照してください。
スタイルのデフォルト
- 長い命令型の本体より、小さく合成可能な関数を優先してください。パフォーマンスや明確さのために本当に必要な場合を除き、手書きのループと
refアキュムレーターよりもList.map/List.filter/List.fold_leftを使ってください。 - ケースが3つ以上ある場合、特にバリアント型では、
if/elseの連鎖よりパターンマッチを優先してください。より慣用的であり、網羅性チェックも自動的に行われます。 - 可能な範囲で関数を全域的にしてください(部分性には
option/resultを返す)。想定される失敗ケースで例外を発生させるのではなく、本当に例外的な状況やプログラマーの誤りに限って例外を使ってください。
表現とアルゴリズムに関するガイダンス
- 可変値を含む配列では、エイリアスに注意してください。
Array.make n valueは同じ初期値を共有します。各要素に新しいオブジェクトが必要な場合はArray.initを使ってください。 - 不変条件を強制するには抽象型を使ってください。クライアントが値を調べられるようにしつつ、構築を制御する必要がある場合は、プライベートレコードまたはバリアントを使ってください。例、永続性の契約、比較関数の落とし穴、符号付き剰余についてはreferences/representation-and-invariants.mdを参照してください。
- カスタムコレクション、再帰的メモ化、動的計画法、グラフアルゴリズムについては、references/data-structures-and-algorithms.mdを参照してください。表現不変条件、アルゴリズムの前提条件、最悪計算量と償却計算量を説明してください。
必要に応じて参照
| 参照するタイミング | リンク |
|---|---|
| 推論エラー、コンパイラメッセージ、型付け規則を読むとき | 型推論とコンパイラーエラー |
| JS/TS/PHP 由来の構文や意味上のイディオムを説明するとき | コア言語のチートシート |
=と==、ミューテーション、値のレイアウトを説明するとき | ランタイムモデル |
| dune プロジェクトのひな型作成や Alcotest スイートの作成をするとき | Dune と Alcotest |
| qcheck、ミューテーションテスト、リンティング、デッドコード用ツールを選ぶとき | テストと品質 |
| カタ、演習、または初学者向けの実用プログラム習得パスについて | 学習リソース |
| 本に登場する具体的なプログラム、データ構造、アルゴリズムについて | Learn Programming with OCaml |
| ベンチマーク結果について | ベンチマーク |