コンテンツにスキップ

OCaml

ドキュメント

インストール

Mac

1
2
3
4
arch -arm64 brew install opam
opam init
opam install dune utop ocaml-lsp-server merlin
opam user-setup install

PrettyPrint

  • ないらしい.
  • 基本的にOCamlでは型のprettyprinterを自分で用意する
  • ppx_derivingを使えばある程度は自動生成できる

Windowsでのopam: インストールしたら『"opam" は内部コマンドまたは外部コマンド、操作可能なプログラムまたはバッチファイルとして認識されていません。』と出る, 2016-09-14

要はレジストリに opam を読み込む処理が書き込まれていてアンインストール時にそれが削除されなかった. 長くはまっていたがようやく解決できた. 本当に良かった.

Twitterの記録

まずは@camloebaさんからのこの注意を喚起しておく.

私が使っているWindows, msys64を入れていたり, 環境変数にHOMEを指定してc:\Users\username的なアレとの食い違いもあったり, Git bashも入っていたりといろいろアレでよくわからなくなっている.

その辺の事情もいろいろあるのかもしれない. 追加で調査を続ける.

OCaml, Haskellと違ってWindowsに厳しい感がある.

追記: いま思うとHaskellも大概Windowsに厳しい. やはりF#がいい.

文字列の等号

  • 参考
  • (==)関数は物理的な等価演算子.
  • 2つのオブジェクトの内容が同じかどうかをテストするなら1つの等号(=)
1
2
3
let s = "1";;
Printf.printf "%B" ((s= "1") = true);;
Printf.printf "%B" ((s=="1") = false);;

メモ

緩募 浅井健一『プログラミングの基礎』の問題13.5の解説についての不明点解消OCamlまたはHaskell

いろいろあって今, 浅井健一『プログラミングの基礎』を読んでいる.

これの問題13.5の解説がよくわからないので, その情報を集めるべく, とりあえず記事としてまとめる. その問題は次のような内容.

上で作った twice に twice 自身を渡して twice twice とすることができる. ここで返ってくる関数はどのような関数か. その型は何か.

twiceは次のような関数だ.

1
2
3
4
let twice f =
  let g x = f (f x)
  in g
val twice : ('a ->'a) ->'a ->'a = <fun>

問題はこれの解答. 本のホームページに載っているのでとりあえず全文引用する.

受け取った関数を4回、実行するような関数を返す関数。例えば、以下。

``` let twice f = let g x = f (f x) in g ;; val twice : ('a ->'a) ->'a ->'a = let g = twice twice ;; val g : ('_a ->'_a) ->'_a ->'_a = let h = g (fun x ->x + 1) ;; val h : int ->int = h 3 ;; - : int = 7

```

関数 h は (fun x ->x + 1) を4回、実行するような関数になっている。

関数 g の型は、

('a ->'a) ->'a ->'a

という多相型になりそうなところだが、そうはならず

('_a ->'_a) ->'_a ->'_a

という特殊な型になる。この型は '_a を一度だけ具体的な型にすることが できるようなもので、実質的に単相な型である。実際、上のように一度、 int ->int 型の関数 (fun x ->x + 1) を g に渡すと、g の型は

g ;; - : (int ->int) ->int ->int =

に固定される。この後、g には int ->int 型以外の関数を渡すことはで きない。このようになっているのは、多相性と後の章で説明する例外や参 照型が干渉するためである。g を多相関数として定義したい場合は、以下 のようにする。

let g x = (twice twice) x ;; val g : ('a ->'a) ->'a ->'a =

で, これがよくわからない. 個人的にほんの少しだけ OCaml よりは慣れている Haskell で軽く書いてみたら, 次のようになった.

1
2
3
4
5
6
7
twice f =
  let g x = f (f x)
  in g
g = twice twice

twice2 f = f . f
h = twice2 twice2

これを REPL に通して :type してみると次の通り.

1
2
3
4
λ>:type twice
twice :: (t ->t) ->t ->t
λ>:type twice2
twice2 :: (a ->a) ->a ->a

この Haskell のコードでの twice が「実質的に単相な型」というやつで, twice2 が多相関数になっているのだと理解している. 最初 Haskell に移植して書いたときは後者の合成の方法で書いていて, 「Haskell と OCaml は挙動が違うのか」と思ったが, どうも同じなようだ (と理解している).

いまのところ, 元の解答の記述でいう「例外や参照型の干渉」は Haskell でも似たことが起こるのだろうという理解. 改めて例外と言われると, 表層的な理解しかしていないことに気付くし, 参照型にいたってははじめて聞いた話で全く理解していない. 実際にどういう話になっているのか, 私にその受け皿が全くないので説明を受けても理解できるとも全く思えない.

しかし気になったのでとりあえずまとめておく. 何かよい解説記事やPDFなどあればぜひ教えてほしい.