OCaml

OCaml の環境構築

Real World OCaml の github リポジトリの以下の wiki に記載されている方法が参考になる

OPAM のインストール

  • OPAM とは OCaml Package Manager
  • パッケージマネージャだけど、OCaml本体もOPAMを通してインストールできる
    • なので最初にOPAMを入れる
    • OPAMのインストール時にOCamlが入るが、特に関係ない

Mac なら brew install opam する。

OPAM uses ~/.opam by default for its package database, so you need to
initialize it first by running (as a normal user):

$  opam init

Run the following to initialize your environment variables:

$  eval `opam config env`

To export the needed variables every time, add them to your dotfiles.
  * On Bash, add them to `~/.bash_profile`.
  * On Zsh, add them to `~/.zprofile` or `~/.zshrc` instead.

Documentation and tutorials are available at https://opam.ocaml.org, or
via "man opam" and "opam --help".

Bash completion has been installed to:
  /usr/local/etc/bash_completion.d

zsh completions have been installed to:
  /usr/local/share/zsh/site-functions
==> Summary
🍺  /usr/local/Cellar/opam/1.2.2_4: 31 files, 16.3MB

OPAMの設定

  • OPAMパッケージデータベース全体は、 ~/.opam に保存される
  • OPAMがおかしくなったら、 ~/ .opam を削除すれば初期化できる
  • opam init のときに聞かれる質問は初心者は y しておけばよい
    • opam init は初回の1回でOK
  • opamは基本的に管理者権限が必要なシステム領域に何かをインストールすることはない
    • 普通はホームディレクトリ $HOME にはいる
    • よってホームディレクトリ配下のコマンドを叩けるように PATH を設定するコマンドがある
      • $ eval opam config env
    • opam$PATH が設定済みかどうかは echo $OCAML_TOPLEVEL_PATH を確認すれば分かる

コンパイラのバージョンを調べる

opam switch コマンドを使う

$ opam switch
--     -- 4.00.0  Official 4.00.0 release
--     -- 4.00.1  Official 4.00.1 release
--     -- 4.01.0  Official 4.01.0 release
--     -- 4.02.0  Official 4.02.0 release
--     -- 4.02.1  Official 4.02.1 release
--     -- 4.02.2  Official 4.02.2 release
4.02.3  I 4.02.3  Official 4.02.3 release
--     -- 4.03.0  Official 4.03.0 release
--     -- 4.04.0  Official 4.04.0 release
--     -- 4.04.1  Official 4.04.1 release
--     -- 4.04.2  Official 4.04.2 release
--     -- 4.05.0  Official 4.05.0 release
4.06.0  C 4.06.0  Official 4.06.0 release
system  I system  System compiler (4.06.0)
# 163 more patched or experimental compilers, use '--all' to show

もしシステムコンパイラが古い場合は以下のコマンドを叩く

$ opam switch 4.06.0 # 最新バージョンを指定する

switch コマンドは .opam 以下にOCamlコンパイラをソースからインストールする(なので時間かかる)。
新しいコンパイラと関連ライブラリは .opam 以下に入る。
上記の例だと ~/.opam/4.06.0 にインストールされる。

# PATHを反映する
$ eval `opam config env`

# ~/.opam 以下にOCamlコンパイラがインストールされている
$ which ocaml{,c,opt}
/Users/hoge/.opam/4.06.0/bin/ocaml
/Users/hoge/.opam/4.06.0/bin/ocamlc
/Users/hoge/.opam/4.06.0/bin/ocamlopt

あとは opam install core utop hoge fuga などして欲しいパッケージをインストールする

utop の設定

utop はOCamlの対話環境
$HOME に設定ファイル .ocamlinit を置いておくと、ファイルに書かれた内容で初期化されて実行される。
なお #hoge はコメントではなく、対話環境向けの設定ディレクティブ。

.ocamlinit の例

#use "topfind";;
#thread;;
#camlp4o;;
#require "core.top";;
#require "core.syntax";;
open Core.Std

上記の設定ファイル例のように、utopでOPAM等で入れたモジュールを読み込む際には #require "base" とディレクティブで読み込んだあとに、open Base;; などする。

utop を入れるほどでもないときは rlwrap ocaml でも問題ない。

Merlin

Merlin は OCaml の開発支援ツール。vim, emacs, vscode など様々なエディタで利用されている。
opam install merlin で入る。
使用するためにはブロジェクトの設定を .merlin ファイルで行う必要がある。

公式リポジトリのWikiの merlin の設定方法 を参考に .merlin を設定する。

以下のブログ記事もとても参考になります。

Sディレクティブ

ソースファイル(ml, mli)が置かれるディレクトリを指定する

# hoge と fuga ディレクトリをソースパスに指定する
S hoge
S fuga

# サブディレクトリを全部追加する
$ piyo/*

# foo以下のサブディレクトリを再帰的に追加する
S foo/**

Bディレクティブ

cmi, cmtファイルの設置場所を設定する

B _build/hoge
B _build/fuga
B _build/* 

PKGディレクティブ

findlib(ocamlfind)で探せるパッケージを指定して、それを補完する。

PKG lwt lwt.unix

EXTディレクティブ

camlp4 で作成された拡張構文をサポートするが、廃止予定とのこと。

EXT lwt

FLGディレクティブ

merlinのオプションを有効にする, オプションの一覧は ocamlmerlin server -flags-help で参照可能

FLG -ppx path-to-executable
FLG -rectypes

RECディレクティブ

.merlinファイルの設定を親ディレクトリからも探すようにする

./.merlin            # RECの設定なし
./lib/.merlin        # RECディレクティブを記述した
./lib/first/.merlin  # RECディレクティブを記述した
./lib/second/.merlin # RECディレクティブを記述した
./src/.merlin        # RECディレクティブを記述した

./.merlin はその .merlin の設定のみ有効になる。
./src ディレクトリでは、./src/.merlin と親ディレクトリにある ./.merlin の設定が有効になる
./lib/first ディレクトリでは、./lib/first/.merlin と親ディレクトリの ./lib/.merlin と更にその親ディレクトリの ./.merlin の設定が有効になる

ocamlfind(findlib)

ocamlfind は OCaml のサードパーティ製のライブラリを、よしなに管理したり見つけたりしてくれるコマンドで、findlib を使って実装されている。
使い方は以下を公式サイトを参照のこと。

ビルドツール

ocamlbuild, OMake, Oasis などがあるが、識者の発言を読む限り、今後新しくOCamlを書く場合は Dune(jbuilder) を使えばよさそう。

Dune(jbuilder)

元々はJaneStreetというOCamlを使っていることで有名な会社が jbuilder という名前で作っていたが、なんか色々あって dune という名前に変更し、OCamlの公式リポジトリ下に移管された。

リポジトリ名はduneだが2018年1月現在はドキュメントの記載やコマンド名は jbuilder のまま。
READMEによれば A full renaming of the documentation and the tool will be done as part of the 1.0 release. とのことで1.0リリースのタイミングで完全にduneになるらしい。

使い方は以下を参考にする