<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: SUZUKI Tetsuya</title>
    <description>The latest articles on DEV Community by SUZUKI Tetsuya (@szktty).</description>
    <link>https://dev.to/szktty</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F321544%2F0de094a1-f2a1-456e-8378-e623da20be74.png</url>
      <title>DEV Community: SUZUKI Tetsuya</title>
      <link>https://dev.to/szktty</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/szktty"/>
    <language>en</language>
    <item>
      <title>OCaml の記号あれこれ</title>
      <dc:creator>SUZUKI Tetsuya</dc:creator>
      <pubDate>Thu, 23 Jan 2020 16:29:20 +0000</pubDate>
      <link>https://dev.to/szktty/ocaml-2n7l</link>
      <guid>https://dev.to/szktty/ocaml-2n7l</guid>
      <description>&lt;p&gt;※この記事は 2014年03月23日 に Qiita に投稿したものです。&lt;/p&gt;

&lt;p&gt;※ちょっと見出しと構成の一部を変えました。&lt;/p&gt;




&lt;p&gt;おはようございます。今日も一日、よろしくお願いします。&lt;/p&gt;

&lt;p&gt;おはようございます。今日も一日、よろしくお願いします。&lt;/p&gt;

&lt;p&gt;大事なことなので二度コピペしました。おはようございます、 OCaml ビギナーです。先日、私のコードの diff を眺めていた CVO（最高美夢責任者）が&lt;/p&gt;

&lt;p&gt;「くっ、我がダークヴィムマスターの戦闘力を以てしても皆目検討が付かぬ……これが神の創りし大駱駝（※ OCaml のことらしい）の力……」&lt;/p&gt;

&lt;p&gt;とつぶやかれておりましたので、&lt;/p&gt;

&lt;p&gt;「っふ……駱眼（※ OCaml のコードを見抜く第三の目。慈悲はない）を持たぬ者にはわからんだろう……ククク、俺の右眼が疼くわ！（花粉の季節はつらいです）」&lt;/p&gt;

&lt;p&gt;と突き放しておきましたが、はて具体的に何がわからなかったのか聞きそびれました。ところで私は、 OCaml の実用的なコードに含まれる見慣れない記号の多さに面食らった覚えがあります。最近になってやっとだいたいの記号の意味がつかめてきましたので、メモしておきます。&lt;/p&gt;

&lt;p&gt;以下、並び順は適当な個人的指標です。 &lt;strong&gt;実際の遭遇傾向とまったく関係ない&lt;/strong&gt; のであしからず。 &lt;code&gt;#&lt;/code&gt; で始まるサンプルコードは &lt;code&gt;ocaml&lt;/code&gt; （トップレベル対話環境）の入力です。&lt;/p&gt;

&lt;h2&gt;
  
  
  レアリティ：N
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;(* ... *)&lt;/code&gt; &lt;code&gt;(** ... *)&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;コメントです。アスタリスク二つで始まるコメント &lt;code&gt;(** ... *)&lt;/code&gt; は &lt;a href="http://ocaml.jp/refman/ch15.html"&gt;Ocamldoc&lt;/a&gt; で抽出できるらしいです。例えばこんな感じ&lt;a href="https://realworldocaml.org/v1/en/html/files-modules-and-programs.html"&gt;（たいした意味もなく Real World OCaml より抜粋）&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(** Bump the frequency count for the given string. *)
val touch : (string * int) list -&amp;gt; string -&amp;gt; (string * int) list
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;[ ... ]&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;リスト（&lt;code&gt;list&lt;/code&gt; 型）を生成します。要素の区切り文字には &lt;code&gt;;&lt;/code&gt; を使います。&lt;/p&gt;

&lt;p&gt;例:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# let words = ["foo"; "bar"; "baz"];;
val words : string list = ["foo"; "bar"; "baz"]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;配列やリストの要素の区切りが &lt;code&gt;,&lt;/code&gt; である言語に慣れていると、&lt;a href="http://d.hatena.ne.jp/keigoi/20101223/1293074938"&gt;思わぬタイミングではまることがある&lt;/a&gt;ので要注意です。&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;,&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;タプルを生成します。ただし、タプルの型は各要素を &lt;code&gt;*&lt;/code&gt; で区切って表します。型の定義と値の生成とで使う記号が異なるので、私はしばらくの間ときどき間違えました。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(* 型の定義 *)
type name = string * string

(* タプルの生成 *)
let johndoe = ("John", "Doe")

(* パターンマッチ *)
match s with
| (first, last) -&amp;gt; Printf.printf "my name is %s %s" first last
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;;&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;文の区切りです。と言っても OCaml の文法の大半はこの区切りが不要なので、コードの短い関数ではあまり使いません。すでに上で触れているように、リスト（以下）やレコードの要素を区切るのにもこの記号を使います。&lt;/p&gt;

&lt;p&gt;しかし、なぜ区切り記号が &lt;code&gt;;&lt;/code&gt; だったり &lt;code&gt;,&lt;/code&gt; だったりするのか？ これには&lt;a href="https://bitbucket.org/camlspotter/ocaml-zippy-tutorial-in-japanese/src/7e5943ed17edf58f370c34feeb218a30cc09143f/random_memo.rst?at=default#rst-header-list-tuple"&gt;一貫性がある&lt;/a&gt;らしいですよ。なるほど、そう言われるとそうですね。&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;&amp;amp;&amp;amp;&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;論理積（AND）の演算子です。まあ想像つきますよね。 &lt;code&gt;and&lt;/code&gt; もありますが、こちらは別の目的で使われる文法です。&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;||&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;論理和（OR）の演算子です。 &lt;code&gt;or&lt;/code&gt; も予約語に含まれていますが、現在は deprecated です。&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;::&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;リストを合成する演算子です。 &lt;code&gt;x :: xs&lt;/code&gt; で &lt;code&gt;xs&lt;/code&gt; の先頭に &lt;code&gt;x&lt;/code&gt; を追加したリストを生成します。&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;'&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;シングルクオートは識別子に使えます。 &lt;code&gt;x'&lt;/code&gt; と言う変数名も、 &lt;code&gt;f'&lt;/code&gt; と言う関数名も OK です。&lt;/p&gt;

&lt;p&gt;ですが、 &lt;code&gt;'a&lt;/code&gt; の形の変数は定義できません。これは型変数と言って（&lt;a href="https://www.google.co.jp/#q=ocaml+%E5%9E%8B%E5%A4%89%E6%95%B0"&gt;Web で検索！&lt;/a&gt;）、型の表記に使われます。&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;|&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;バリアント型とパターンマッチで、複数のパターンを区切って書くのに使います。これはコードを見るのが早いですね（どれもか）。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(* バリアント型の定義 *)
type foobar =
    Foo (* | Foo としてもよい *)
  | Bar
  | Baz

(* パターンマッチ *)
match v with
| Foo -&amp;gt; ...
| Bar -&amp;gt; ...
| Baz -&amp;gt; ...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;-&amp;gt;&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;パターンマッチのガードまたは型の表記に使われます。例えば、文字列の特定の位置の文字を取得する関数 &lt;code&gt;String.get&lt;/code&gt; の型は &lt;code&gt;string -&amp;gt; int -&amp;gt; char&lt;/code&gt; です。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(* パターンマッチ *)
match v with
| Foo -&amp;gt; ...
| Bar -&amp;gt; ...
| Baz -&amp;gt; ...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;()&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;括弧の間には何も入りません。これは &lt;code&gt;unit&lt;/code&gt; 型と呼ばれる何も持たないタプルで……他の言語で言う void ですね。 &lt;/p&gt;

&lt;p&gt;引数に &lt;code&gt;()&lt;/code&gt; を指定している関数を見つけたら、それは特に引数を必要としない関数です。関数は何かしら引数をつけないと呼び出せないので、型が &lt;code&gt;unit -&amp;gt;&lt;/code&gt; で始まる関数は &lt;code&gt;()&lt;/code&gt; を指定すれば呼び出せます。例えばこんなの:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Sys.getcwd ();; (* カレントディレクトリを取得する *)
- : string = "/Volumes/Users/szktty"
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;エントリポイントの &lt;code&gt;let () = ...&lt;/code&gt; もこの記号ですね。こちらは引数ではなくパターンマッチですけど。&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;^&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;文字列を連結する演算子です。 &lt;a href="https://bitbucket.org/camlspotter/ocaml-zippy-tutorial-in-japanese/src/7e5943ed17edf58f370c34feeb218a30cc09143f/random_memo.rst?at=default#rst-header-string-mutable"&gt;OCaml の文字列は可変&lt;/a&gt;ですが、拡張はできません。この演算子を使うと新しい文字列が生成されるので、&lt;a href="https://bitbucket.org/camlspotter/ocaml-zippy-tutorial-in-japanese/src/7e5943ed17edf58f370c34feeb218a30cc09143f/random_memo.rst?at=default#rst-header-id7"&gt;連結の繰り返しには &lt;code&gt;Buffer&lt;/code&gt; を使いましょう&lt;/a&gt;（これを書いているヤツは、ここに来て「アッ、俺がコピペしてた &lt;code&gt;Buffer&lt;/code&gt; はこれだったのか！」と気づいた）。&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;+.&lt;/code&gt; &lt;code&gt;-.&lt;/code&gt; &lt;code&gt;*.&lt;/code&gt; &lt;code&gt;/.&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;浮動小数点数同士を加算する演算子です。 OCaml では多重定義が禁止されているので〜と言った理屈はともかく、整数には整数同士の、浮動小数点数には浮動小数点数同士の演算子を使わなければならないため、 &lt;code&gt;1 + 0.1&lt;/code&gt; とか &lt;code&gt;1.5 + 3.2&lt;/code&gt; のような式は書けません。&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;_&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;識別子に使える記号です。パターンマッチではワイルドカードと呼ばれますが、実は他の変数と比べて特殊な働きをするわけではありません。 &lt;code&gt;_&lt;/code&gt; としても &lt;code&gt;v&lt;/code&gt; としても、任意の値にマッチします:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;match exp with
| 0 -&amp;gt; ...
| v -&amp;gt; ... (* 0 以外の値にマッチする *)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;ただし、この記号を変数名（または関数名）の先頭につけると、その変数はある警告をすり抜けます。通常は定義した変数をまったく使わないと未使用の変数としてコンパイラに警告されますが、そのチェックが行われません。つい &lt;a href="https://bitbucket.org/camlspotter/ocaml-zippy-tutorial-in-japanese/src/7e5943ed17edf58f370c34feeb218a30cc09143f/random_memo.rst?at=default#rst-header-let"&gt;&lt;code&gt;let _ =&lt;/code&gt; と書かないように気をつけましょう。&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;match exp with
| 0 -&amp;gt; 0
| v -&amp;gt; 1 (* v を使っていないため、未使用の変数として警告される *)

match exp with
| 0 -&amp;gt; 0
| _ -&amp;gt; 1 (* "_" に対しては警告されない *)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;もう一つ、これは別段言語仕様でも強制でもありませんが、命名の慣習として識別子（特にレコードのフィールド名）の最後に &lt;code&gt;_&lt;/code&gt; をつける場合があります。よく見る/やるのは &lt;code&gt;end_&lt;/code&gt; や &lt;code&gt;to_&lt;/code&gt; ですね。理由は単純で、同名の予約語 &lt;code&gt;end&lt;/code&gt; &lt;code&gt;to&lt;/code&gt; があるからです。頭ひねって別名考えても回りくどいだけだし、二文字三文字の単語を省略するとわかりにくいし、それじゃあお尻に &lt;code&gt;_&lt;/code&gt; をくっつけとけば……良心が疼くほどでもないっしょ？&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type location = {
  start : int;
  end_ : int;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  レアリティ：R
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;[| ... |]&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;配列（&lt;code&gt;array&lt;/code&gt; 型）を生成する文法です。これで &lt;code&gt;[...]&lt;/code&gt; との区別は完璧ですね！&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# [|1; 2; 3|];;
- : int array = [|1; 2; 3|]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;:=&lt;/code&gt; &lt;code&gt;&amp;lt;-&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;OCaml にも&lt;a href="http://ocaml.jp/%E7%A0%B4%E5%A3%8A%E7%9A%84%E4%BB%A3%E5%85%A5"&gt;破壊的代入&lt;/a&gt;ってやつがあります。ただしどの変数でもと言うわけにはいかず、 &lt;code&gt;ref&lt;/code&gt; キーワードを指定した変数か、 &lt;code&gt;mutable&lt;/code&gt; キーワードを指定した（レコードの）フィールドに限られます。前者と後者で記号がなぜだか異なりますが、見りゃわかると思うのでもう何も怖くない！&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;=&lt;/code&gt; &lt;code&gt;&amp;lt;&amp;gt;&lt;/code&gt; &lt;code&gt;==&lt;/code&gt; &lt;code&gt;!=&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;等値演算子です。 Jane Street Core ライブラリを使っている場合、 &lt;code&gt;==&lt;/code&gt; か &lt;code&gt;!=&lt;/code&gt; を使うと次のエラーメッセージが表示されます。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Error: This expression has type int but an expression was expected of type
               [ `Consider_using_phys_equal ]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;なんのこっちゃ？ と思っていたのですが、 OCaml では &lt;code&gt;==&lt;/code&gt; と &lt;code&gt;!=&lt;/code&gt; はポインタ同士を比較する演算子です。ですから、私のように文字列を &lt;code&gt;==&lt;/code&gt; で比較してしまうと想定外の結果ではまります（これは Jane Street Core を使っていなくても同じです）。こればかりはコンパイラもバグかどうか判別できません。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(* true にならない！ *)
# "a" == "a";;
- : bool = false
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;あなたが求めている演算子は &lt;code&gt;=&lt;/code&gt; と &lt;code&gt;&amp;lt;&amp;gt;&lt;/code&gt; ですね。異論は認めない。恥辱に塗れた己の黒歴史と共に &lt;a href="https://bitbucket.org/camlspotter/ocaml-zippy-tutorial-in-japanese/src/7e5943ed17edf58f370c34feeb218a30cc09143f/random_memo.rst?at=default#rst-header-physical-comparison"&gt;&lt;code&gt;==&lt;/code&gt; と &lt;code&gt;!=&lt;/code&gt; を封印して&lt;/a&gt;ドヤリングするのです（誰に&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;~&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;a href="http://ocaml.jp/Chapter%204%20%E3%83%A9%E3%83%99%E3%83%AB%E3%81%A8%E3%83%90%E3%83%AA%E3%82%A2%E3%83%B3%E3%83%88"&gt;ラベル付き引数&lt;/a&gt;で使われる記号です。ラベル付き引数は使おうが使うまいがあなたの好きにすればいい機能ですが、&lt;a href="http://d.hatena.ne.jp/camlspotter/20090106/1231196430"&gt;お前のラベル定義なんざ無視してもコンパイルが通ります（そう、デフォルトの警告設定ならね）&lt;/a&gt;。何が言いたいのかって……面倒臭いのでリンク先を読んでください。それも面倒臭ければ &lt;strong&gt;&lt;code&gt;-warn-error L&lt;/code&gt;&lt;/strong&gt; を指定しとけば損しないです。&lt;/p&gt;

&lt;p&gt;ちなみに私もつい最近まで警告オプションを設定していなかったため、 API リファレンスにラベルが書いてあっても理解を後回しにして（=調べるのをさぼって）引数を指定していました。もし私が OCaml のエラい人とペアプロでもしようものなら、「うわっ…君の年収、低すぎ…」と蔑みの視線が向けられること確実です（俺の年収は関係ねえだろ！）。&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;?&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;a href="http://ocaml.jp/Chapter%204%20%E3%83%A9%E3%83%99%E3%83%AB%E3%81%A8%E3%83%90%E3%83%AA%E3%82%A2%E3%83%B3%E3%83%88"&gt;オプショナル引数&lt;/a&gt;=省略できるラベル付き引数 で使われる記号です。 OCaml では関数に定義より少ない引数を与えると&lt;a href="http://ocaml.jp/OCaml%E5%85%A5%E9%96%80%282%29"&gt;部分適用&lt;/a&gt;として扱われるため、オプショナル引数の使い方に注意が必要です。&lt;/p&gt;

&lt;p&gt;私は引数を省略できると知って、さっそく引数いらずの関数を定義しようとしたのですが、&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(* 警告されつつもコンパイルは通るけれど…… *)
# let test ?(x=0) = x;;
Warning 16: this optional argument cannot be erased.
val test : ?x:int -&amp;gt; int = &amp;lt;fun&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;何やら警告が出ます。しかし、たかが初見の警告程度で怯む私ではありません。 OCaml ビギナーの考える引数いらずの関数呼び出しとは……これだっ！&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(* 引数がなければ呼び出せません *)
# test;;
- : ?x:int -&amp;gt; int = &amp;lt;fun&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;……ですよねー。うーん、じゃあこうかなとやってみる俺、さすがビギナーです。目のつけどころが違う。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(* ダメなものはダメです。型が違うだろ！ *)
# test ();;
Error: The function applied to this argument has type ?x:int -&amp;gt; int
This argument cannot be applied without label
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;むむむ……仕方がない、妥協して引数を与えてやろう。これはどうだ？&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(* ラベルなし引数を与えるとエラー *)
# test 0;;
Error: The function applied to this argument has type ?x:int -&amp;gt; int
This argument cannot be applied without label
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;うっ……結局、ラベルを指定すれば呼べました。でも、もはや引数省略の意味がないですね。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(* オプショナル引数とは何だったのか *)
# test ~x:0;;
- : int = 0
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;どうしてこうなるのかと言えば、 OCaml では&lt;a href="http://ocaml.org/learn/tutorials/basics.ja.html#_3"&gt;関数を呼び出すのに必ず引数が必要&lt;/a&gt;だからです。前述の &lt;code&gt;test ()&lt;/code&gt; は C などのメジャーな言語にある &lt;code&gt;test()&lt;/code&gt; の &lt;code&gt;()&lt;/code&gt; 的な呼び出しベルではなくて、  &lt;code&gt;()&lt;/code&gt; という &lt;code&gt;unit&lt;/code&gt; 型の値を引数として渡す式として解釈されます。すっかり身に付いてしまった手癖で引数ゼロとしたつもりが、実は引数を一つ与えていたんですね。&lt;/p&gt;

&lt;p&gt;さて、オプショナル引数にはもう一つ注意すべき点があります。ご期待通り私はまんまとトラップに引っかかってしまうのですが……（まあこれが、知ったかぶりで走り出す私のビギナーたる所以です）最後の引数をオプショナル引数にはできません。やってみると、&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(* 同じ警告が出る *)
# let test y ?(x=0) = x + y;;
Warning 16: this optional argument cannot be erased.
val test : int -&amp;gt; ?x:int -&amp;gt; int = &amp;lt;fun&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;先程と同じ警告が出ます。そうなるとやはり、&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(* これじゃだめ *)
# test 1;;
- : ?x:int -&amp;gt; int = &amp;lt;fun&amp;gt;

(* ラベルを指定すれば OK 、だけど…… *)
# test ~x:1 2;;
- : int = 3
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;ビギナーの思うようには動きません。オプショナル引数は最後から二番目までに定義しましょう。暇を見つけて「部分適用」をヒントに考えてみると、あなたの OCaml レベルキャップを引き上げられるかもしれません。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# let test ?(x=1) y = x + y;;
val test : ?x:int -&amp;gt; int -&amp;gt; int = &amp;lt;fun&amp;gt;
# test 2;;
- : int = 3
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;まあ実は、どちらのミスもコンパイラオプションの &lt;strong&gt;&lt;code&gt;-warn-error&lt;/code&gt; に 16 か X を指定しておけば防げる&lt;/strong&gt;んですけどね。デフォルトでオンにしてくれてもよさそうですけどね。&lt;/p&gt;

&lt;h2&gt;
  
  
  レアリティ：SR
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;`&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;a href="http://d.hatena.ne.jp/osiire/20090510/1241957550"&gt;多相バリアント&lt;/a&gt;を示す記号です。多相バリアントにはこの他にも &lt;code&gt;[&amp;gt;&lt;/code&gt; や &lt;code&gt;[&amp;lt;&lt;/code&gt; の記号があって、一見するとまあわけがわからないので後回しにしたくなりますね。&lt;/p&gt;

&lt;p&gt;でもこれ、&lt;a href="http://d.hatena.ne.jp/osiire/20090516"&gt;早めに理解しておくとよさそうです&lt;/a&gt;。それまで私はバリアント型を定義するのにどうも身構えてしまって戻り値に &lt;code&gt;bool&lt;/code&gt; を使いがちでしたが、&lt;a href="https://bitbucket.org/camlspotter/ocaml-zippy-tutorial-in-japanese/src/7e5943ed17edf58f370c34feeb218a30cc09143f/random_memo.rst?at=default#rst-header-bool"&gt;多相バリアントなら気楽にわかりやすい戻り値を使えます&lt;/a&gt;しね。&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;@@&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;4.01.0 から導入された演算子で、&lt;a href="http://d.hatena.ne.jp/camlspotter/20101210/1291958542"&gt;貴様の眼に映るすべての括弧を吹き飛ばす暗黒 OCa&lt;/a&gt;……まあ、 Haskell で言うアレ（&lt;code&gt;$&lt;/code&gt;）です。たびたび使うので、レアな記号でもないんですけど。&lt;/p&gt;

&lt;p&gt;さてビギナーの私は、「おお括弧を省ける」と喜び勇んでこう書いてみたわけですよ。みんな一度はやるよね？ あれ、やらない？&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;`&lt;br&gt;
(* 括弧を省け……ない……だと……？ *)&lt;/p&gt;

&lt;h1&gt;
  
  
  Some @@ x + y;;
&lt;/h1&gt;

&lt;p&gt;Error: The constructor Some expects 1 argument(s),&lt;br&gt;
       but is applied here to 0 argument(s)&lt;br&gt;
`&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Some&lt;/code&gt; は &lt;code&gt;option&lt;/code&gt; 型のコンストラクタなんですが、 OCaml では&lt;a href="http://ocaml.jp/%E5%9E%8B%E3%81%AE%E5%AE%9A%E7%BE%A9"&gt;コンストラクタは関数ではない&lt;/a&gt;ため &lt;code&gt;@@&lt;/code&gt; が使えません。この場合は横着せずに  &lt;code&gt;Some (x + y)&lt;/code&gt; と書くほかありません。&lt;/p&gt;

&lt;p&gt;ちなみに、私はたまに &lt;code&gt;@&lt;/code&gt; と間違えて型エラーを指摘されます。二文字打つのも面倒くさいし、&lt;a href="https://bitbucket.org/camlspotter/ocaml-zippy-tutorial-in-japanese/src/7e5943ed17edf58f370c34feeb218a30cc09143f/random_memo.rst?at=default#rst-header-haskell-f"&gt;&lt;code&gt;&amp;amp;&lt;/code&gt; を用意しようかな。&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;|&amp;gt;&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;@@&lt;/code&gt; の逆を行く演算子です。例えば x と y を足すだけの単純な関数 &lt;code&gt;test&lt;/code&gt; があったとして、&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;`&lt;/p&gt;

&lt;h1&gt;
  
  
  let test x y = x + y;;
&lt;/h1&gt;

&lt;p&gt;val test : int -&amp;gt; int -&amp;gt; int = &lt;br&gt;
`&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;@@&lt;/code&gt; を使うとこう書けます。&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;`&lt;/p&gt;

&lt;h1&gt;
  
  
  test 1 @@ 2 + 3;;
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;: int = 6
`&lt;code&gt;&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;|&amp;gt;&lt;/code&gt; を使うとこう書けます。&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;`&lt;/p&gt;

&lt;h1&gt;
  
  
  2 + 3 |&amp;gt; test 1;;
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;: int = 6
`&lt;code&gt;&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;@@&lt;/code&gt; はわかったけど、 &lt;code&gt;|&amp;gt;&lt;/code&gt; はどういうときに使えばいいのかって？ え……ビギナーの私にそれを聞きますか。あなたの実際書くコードから無限デジャブめいたエイジングスメルが漂い始めたら考えればいいんじゃないですか？ 私も本気出した暁には考えます。&lt;/p&gt;

&lt;h2&gt;
  
  
  レアリティ：SSR
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;;;&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;私も &lt;a href="https://bitbucket.org/camlspotter/ocaml-zippy-tutorial-in-japanese/src/7e5943ed17edf58f370c34feeb218a30cc09143f/random_memo.rst?at=default#rst-header-id1"&gt;&lt;code&gt;ocaml&lt;/code&gt; トップレベルは使わない&lt;/a&gt;のでよーけ知らんで。&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;@&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;この記号を&lt;a href="https://bitbucket.org/camlspotter/ocaml-zippy-tutorial-in-japanese/src/7e5943ed17edf58f370c34feeb218a30cc09143f/random_memo.rst?at=default#rst-header-xs-x"&gt;絶対に夜一人で見てはいけない……。&lt;/a&gt;いいか、絶対にだ！&lt;/p&gt;

</description>
      <category>ocaml</category>
    </item>
    <item>
      <title>OCaml の警告オプション（の一部）</title>
      <dc:creator>SUZUKI Tetsuya</dc:creator>
      <pubDate>Thu, 23 Jan 2020 16:19:39 +0000</pubDate>
      <link>https://dev.to/szktty/ocaml-14eg</link>
      <guid>https://dev.to/szktty/ocaml-14eg</guid>
      <description>&lt;p&gt;※この記事は 2014年05月05日 に Qiita に投稿したものです。&lt;/p&gt;




&lt;p&gt;警告、してますか？&lt;/p&gt;

&lt;p&gt;こんにちは、 OCaml タグの投稿が少ないのをいいことに好き勝手書いてる OCaml ビギナーです。私しか OCaml 書く人がいないんで、仕事でも好き勝手書いてます。書く人がいなければなかなかレビューを受ける機会もないので、独り言が増えました。ぼっちレビューです。&lt;/p&gt;

&lt;p&gt;「ちょっとアンタ、ナニよこれ？ 関数名もコンストラクタ名も &lt;code&gt;CamelCase&lt;/code&gt; で書いてあるじゃない！ 関数名は &lt;code&gt;snake_case&lt;/code&gt; 、コンストラクタ名は先頭大文字の &lt;code&gt;Snake_case&lt;/code&gt; に直しなさいヨ！」&lt;br&gt;
「イヤァヨ、そんなのキモいじゃない。モジュールとコンストラクタで先頭を大文字にすんなら、ぜーんぶ &lt;code&gt;CamelCase&lt;/code&gt; で揃えるのがモプ、すなわちモダン・プログラマーなのヨォ。あらヤダ、これって駱駝っぽくてカッコよくなくない？」&lt;br&gt;
「このバカチン！ 修正コミットしたら&lt;a href="http://caml.inria.fr/resources/doc/guides/guidelines.en.html"&gt;ガイドライン&lt;/a&gt;を百遍音読しておきなさいヨ！（日本語訳は&lt;a href="http://www.math.sansu.org/u/pwplus/index.php?OCaml%2Fguideline"&gt;ココ&lt;/a&gt;ヨ！）」&lt;br&gt;
「ナニサ、アンタたちだってぶれっぶれじゃないの。モジュール名を原則 &lt;code&gt;Snake_case&lt;/code&gt; にしてたり、コンストラクタ名を &lt;code&gt;CamelCase&lt;/code&gt; で通す人も見たわヨォ。やぁねェ、いい歳してカビ臭いガイドラインで束縛したがる男って。 30 インチのワイドディスプレイがデフォルトの時代に 80 カラム幅って何？ アンタら加齢臭がキツイのヨッ！」&lt;br&gt;
「ダマらっしゃい、ミドル脂臭風情がッ！ アンタみたいなペーペーはね、十年ゲザってアタシのありがたーいアドバイスを聞いてりゃいいのヨ！ だいたいアンタはねェ……あらまァ、この &lt;code&gt;open&lt;/code&gt; の羅列はナニ？ これじゃどこの馬の骨に依存してんだかわかりゃしない。いい加減に警告オプションを指定おしッ！ すべての &lt;code&gt;open&lt;/code&gt; を駆逐ヨッ！」&lt;br&gt;
「ハイハイ、ワカリマシタ……アァーン、警告ちゃんったら 45 もあるじゃないのォ。ンもぉメンドくさくなっちゃったわアタシぃ。こうなったらゼンブ無視よ無視」&lt;br&gt;
「マッタク、最近の若いコときたら！ 先人の血と汗とヒゲを何だと思ってるのかしら。ブツブツ……」&lt;/p&gt;

&lt;p&gt;アッハイ、余計な前説にカマってないで先を進めます。&lt;a href="http://caml.inria.fr/pub/docs/manual-ocaml-4.01/native.html"&gt;バージョン 4.01&lt;/a&gt; で利用できる警告の数は 45 + アルファベットの数だけあります（アルファベットは数字の別名またはグループ化です）。 45 も警告があると調べるのがしんどくて、個人的に気になったやつを調べるだけで力尽きました。&lt;/p&gt;
&lt;h2&gt;
  
  
  【すべてのエラーを】警告 A【消し去りたい】
&lt;/h2&gt;

&lt;p&gt;すべての警告を有効にします。&lt;/p&gt;

&lt;p&gt;……&lt;/p&gt;

&lt;p&gt;はい死んだ！ 今君のソースコード死んだよ！ 「とりあえず全部エラーにしとけ」と思って &lt;code&gt;-warn-error A&lt;/code&gt; ってやっただろ！ ずらずら出てきた警告を潰そうとして手をつけたのはいいが、メッセージの意味がわかんなくて直しきれないんだろ！ ビルドできなくなっちゃっただろ！ あぁん？ 怒ってないから正直に言ってみろ！&lt;/p&gt;

&lt;p&gt;ハァハァ……き、貴様のようなビギナーはすべての警告を有効にしつつ、そこから厳し過ぎてコーディングがしんどいものを除くのが吉です。&lt;/p&gt;

&lt;p&gt;警告に関するオプションは &lt;code&gt;-w&lt;/code&gt;　と &lt;code&gt;-warn-error&lt;/code&gt; があります。オプション引数には有効にしたい警告のリストを指定するのですが…… &lt;code&gt;-w&lt;/code&gt; のフォーマットが少し風変わりでして、任意の警告番号の範囲をまとめて有効化/無効化したり、 &lt;code&gt;-warn-error&lt;/code&gt; を使わずに警告をエラー扱いにできます。詳しい解説書なら事細かに説明するところかもしれ……しないか。ただ、お前らビギナーはしちめんどくさいフォーマットを覚える必要はなく、消去法で警告を指定するやり方のみ知っておけばいいと思います。フォーマットはこうです。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;-w A-?-?-... -warn-error A
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;無効にしたい警告を &lt;code&gt;-&lt;/code&gt; で区切ります（&lt;code&gt;-&lt;/code&gt; は警告を無効にする指示子です）。例えば、私は次のオプションを指定しています。まあ、ほぼ受け売りなんですけど（い、一応自分でも調べて選んだんだからねっ！）。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;-w A-4-9-40-42-44-45 -warn-error A
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;このオプションは 4, 9, 40, 42, 44, 45 を &lt;strong&gt;除く&lt;/strong&gt; すべての警告を有効にし、かつエラーにします。これに 6 を加える場合もあるようですが、プロジェクトに応じて判断してください。&lt;/p&gt;

&lt;p&gt;ちなみに、デフォルトの警告設定はこうです。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;-w +a-4-6-7-9-27-29-32..39-41..42-44-45
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;すべての警告から 4, 6, 7, 9, 27, 29, 32 から 39, 41 から 42, 44, 45 を除くもの、つまり 1, 2, 3, 5, 8, 10 から 26, 30 から 31, 40, 43 がデフォルトで有効です。何言ってんだかわからないと思いますが、デフォルトの設定では結構適当なコードが書けちゃいます。&lt;/p&gt;

&lt;p&gt;ちなみに、 &lt;a href="https://realworldocaml.org/v1/en/html/records.html"&gt;Real World OCaml&lt;/a&gt; のコードのコンパイルに使われている警告設定はこうです（"Compiler Warnings" のところ）。あくまで本のための警告設定ですから、実務でもこれでいいのかは知りません。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;-w @A-4-33-41-42-43-34-44
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  【ワイルドカード】警告 4 または E【禁止令】
&lt;/h2&gt;

&lt;p&gt;バリアント型に後からコンストラクタが追加されても成立するパターンマッチに対して警告します、とあります。早い話が、ワイルドカードを使った手抜きのパターンマッチを見つけるとぶん殴りに来るようです。（ドキュメントではこういうパターンマッチを "fragile pattern matching" と呼んでいるようですが……どこかで定義されているのかな？）&lt;/p&gt;

&lt;p&gt;例:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type t =
  | A
  | B
  | C

let is_a t =
  match t with
  | A -&amp;gt; true
  | _ -&amp;gt; false
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;コンパイル結果:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;File "e.ml", line 7, characters 2-47:
Warning 4: this pattern-matching is fragile.
It will remain exhaustive when constructors are added to type t.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;関数 &lt;code&gt;is_a&lt;/code&gt; のパターンマッチでは、 &lt;code&gt;A&lt;/code&gt; 以外のコンストラクタをワイルドカードで無視しています。例えばコードを書き進めるうちに &lt;code&gt;t&lt;/code&gt; 型には &lt;code&gt;D&lt;/code&gt; も必要だったとわかったとします。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight ocaml"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nc"&gt;A&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nc"&gt;B&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nc"&gt;C&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nc"&gt;D&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;このように書き足したとしても、 &lt;code&gt;is_a&lt;/code&gt; を変更する必要はないですね。ワイルドカードで無視しちゃうんで。この警告を有効にすると、ワイルドカードを使わずにこのように書かないといけません。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight ocaml"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;is_a&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="k"&gt;with&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nc"&gt;A&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="bp"&gt;true&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nc"&gt;B&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="bp"&gt;false&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nc"&gt;C&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="bp"&gt;false&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nc"&gt;D&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="bp"&gt;false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;逐一こう書くようにすれば、後から追加したコンストラクタがワイルドカードによっていい加減に扱われることで発生するバグを防げそうです。しかし反比例してタイプ量が相当増えます。めんどくさいですね。めんどくさいですが、とてつもなく厳密なコーディングが要求されるような大人数参加のプロジェクトでは有用なのかもしれません（そうは言っても、パターンマッチを適当に実装されれば無駄ですが）。でもやっぱりあまりにもめんどくさいんで、私は無効にしてます。&lt;/p&gt;

&lt;p&gt;ところで、 &lt;a href="http://gallium.inria.fr/~fpottier/menhir/"&gt;Menhir（OCaml 用の yacc）&lt;/a&gt; を使う場合には注意が必要です。 Menhir がこの警告に引っかかるコードを生成するので、 &lt;code&gt;-warn-error&lt;/code&gt; でこの警告をエラー扱いにするとビルドが止まってしまいます。それもあって、私は無効にしてます。&lt;/p&gt;

&lt;h2&gt;
  
  
  【ラベル嫌いを】警告 6 または L【誅したい】
&lt;/h2&gt;

&lt;p&gt;この警告を有効にすると、ラベル付き引数に対してラベルなしの引数を与えた場合に警告されます。例によって適当な例:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight ocaml"&gt;&lt;code&gt;&lt;span class="o"&gt;#&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;test&lt;/span&gt; &lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;;;&lt;/span&gt;
&lt;span class="k"&gt;val&lt;/span&gt; &lt;span class="n"&gt;test&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;fun&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;#&lt;/span&gt; &lt;span class="n"&gt;test&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;;&lt;/span&gt;
&lt;span class="nc"&gt;Warning&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;labels&lt;/span&gt; &lt;span class="n"&gt;were&lt;/span&gt; &lt;span class="n"&gt;omitted&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="n"&gt;this&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;デフォルトではこの警告は無効にされており、警告 A を指定してもこの警告を外す人もいます。なんでしょうね、この避けられっぷりは。古参の OCaml ユーザーにはラベルが体に馴染まない方が多いんでしょうか。ただ、引数の順序を間違えるとバグにつながるからラベルを使うという側面もあるので、特に理由がないのなら、私はこの警告を有効にしておくのがいいと思います。&lt;/p&gt;

&lt;h2&gt;
  
  
  【俺の名前を】警告 9 または R【言ってみろ！】
&lt;/h2&gt;

&lt;p&gt;レコードをパターンマッチする際、フィールドをすべて指定しないと警告されます。&lt;/p&gt;

&lt;p&gt;とありますが……私がぼっちプログラマーだからか、めんどくささとのトレードオフを考えたときのメリットがわからないんですよね。コンパイルできた時点でレコードの型は特定されてるんじゃないの？ と思ったんで、一部のフィールドの型と名前が共通するレコード型を複数用意して、デフォルトの警告セットでパターンマッチを試してみますと……&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight ocaml"&gt;&lt;code&gt;&lt;span class="o"&gt;#&lt;/span&gt; &lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;};;&lt;/span&gt;
&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="o"&gt;#&lt;/span&gt; &lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;};;&lt;/span&gt;
&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="o"&gt;#&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;test&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;;;&lt;/span&gt;
&lt;span class="k"&gt;val&lt;/span&gt; &lt;span class="n"&gt;test&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;fun&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;あらま、通っちゃったよ。確かにコンパイル時にレコードの型は特定されたようですが、 &lt;code&gt;b&lt;/code&gt; が選択されています。俺が期待してたのは &lt;code&gt;a&lt;/code&gt; なんだよ！（無茶振り失礼）&lt;/p&gt;

&lt;p&gt;ちっ。すべての警告を有効にして再び実行してみます:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight ocaml"&gt;&lt;code&gt;&lt;span class="o"&gt;#&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;test&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;;;&lt;/span&gt;
&lt;span class="nc"&gt;Warning&lt;/span&gt; &lt;span class="mi"&gt;41&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;these&lt;/span&gt; &lt;span class="n"&gt;field&lt;/span&gt; &lt;span class="n"&gt;labels&lt;/span&gt; &lt;span class="n"&gt;belong&lt;/span&gt; &lt;span class="k"&gt;to&lt;/span&gt; &lt;span class="n"&gt;several&lt;/span&gt; &lt;span class="n"&gt;types&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;
&lt;span class="nc"&gt;The&lt;/span&gt; &lt;span class="n"&gt;first&lt;/span&gt; &lt;span class="n"&gt;one&lt;/span&gt; &lt;span class="n"&gt;was&lt;/span&gt; &lt;span class="n"&gt;selected&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="nc"&gt;Please&lt;/span&gt; &lt;span class="n"&gt;disambiguate&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;this&lt;/span&gt; &lt;span class="n"&gt;is&lt;/span&gt; &lt;span class="n"&gt;wrong&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;span class="nc"&gt;Warning&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;following&lt;/span&gt; &lt;span class="n"&gt;labels&lt;/span&gt; &lt;span class="n"&gt;are&lt;/span&gt; &lt;span class="n"&gt;not&lt;/span&gt; &lt;span class="n"&gt;bound&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;this&lt;/span&gt; &lt;span class="n"&gt;record&lt;/span&gt; &lt;span class="n"&gt;pattern&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;span class="n"&gt;c&lt;/span&gt;
&lt;span class="nc"&gt;Either&lt;/span&gt; &lt;span class="n"&gt;bind&lt;/span&gt; &lt;span class="n"&gt;these&lt;/span&gt; &lt;span class="n"&gt;labels&lt;/span&gt; &lt;span class="n"&gt;explicitly&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="n"&gt;add&lt;/span&gt; &lt;span class="k"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;_'&lt;/span&gt; &lt;span class="k"&gt;to&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;pattern&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;span class="k"&gt;val&lt;/span&gt; &lt;span class="n"&gt;test&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;fun&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;警告 41 と警告 9 が出力されました。警告 41 のメッセージでは、パターンマッチに対応する型が複数見つかったために片方（&lt;code&gt;b&lt;/code&gt;）を選択したとあります。&lt;/p&gt;

&lt;p&gt;あん？ レコードの型をきちんと指定させたいなら警告 41 を有効にすればいいのでは？ 不備を指摘されたら型名を指定すればいいわけだし:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# let test ({ a = i } : a) j = i + j;;
val test : a -&amp;gt; int -&amp;gt; int = &amp;lt;fun&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;いけますね。一方、警告 9 のメッセージには "Either bind these labels explicitly or add '; _' to the pattern." とある通り、抜け道があるようです。どうやらワイルドカードは使えるんですね。やってみます。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight ocaml"&gt;&lt;code&gt;&lt;span class="o"&gt;#&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;test&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;;;&lt;/span&gt;
&lt;span class="k"&gt;val&lt;/span&gt; &lt;span class="n"&gt;test&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;fun&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;……何も注意されない。この警告、有効にする意味があるんですかね？&lt;/p&gt;

&lt;p&gt;いや待て、この警告は 9 で先の警告は 41 です。数字の差が広いってことは……ぐぐってみますと、 &lt;a href="http://caml.inria.fr/distrib/ocaml-4.01/notes/Changes"&gt;9 はバージョン 3.12.0 で、 41 は 4.00.0 で追加された&lt;/a&gt;ようです。もしかすると、 9 のよりよい警告が 41 なのかもしれません。うん？ それなら若者（ OCaml 歴的な意味で）は、いまさら 9 を使わずともええんちゃう？&lt;/p&gt;

&lt;p&gt;ふむ、しかし何かが引っかかる……&lt;/p&gt;

&lt;p&gt;うむ、どうも私はひでぇ思い違いをしているのかもしれない。もしかしてこの警告は、「複数あるレコード型のうち、いずれか一つを特定できないパターンマッチを指摘するために使う警告 &lt;strong&gt;ではない&lt;/strong&gt; 」のではないでしょうか！&lt;/p&gt;

&lt;p&gt;……。&lt;/p&gt;

&lt;p&gt;てへぺろ☆ (・ω&amp;lt;)&lt;/p&gt;

&lt;h2&gt;
  
  
  【アウトオブ範囲だけど】警告 40【型指定さえあれば問題ないよねっ】
&lt;/h2&gt;

&lt;p&gt;ドキュメントには "Constructor or label name used out of scope." とあり、その通りに読むならスコープ外のコンストラクタやラベル名が使われていれば警告します。でもここで言われているラベル名とは、どうもラベル付き引数のラベルではなく、レコードのフィールド名らしいです。私のコードではコンストラクタよりもレコードのフィールドで引っかかる場合が多かったです。&lt;/p&gt;

&lt;p&gt;例えば、このようなモジュール定義があったとして:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight ocaml"&gt;&lt;code&gt;&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nc"&gt;M&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt;
  &lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 
    &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nc"&gt;Foo&lt;/span&gt; 
    &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nc"&gt;Bar&lt;/span&gt; 
    &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nc"&gt;Baz&lt;/span&gt; 
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;モジュール &lt;code&gt;M&lt;/code&gt; とは異なる名前空間で（ &lt;code&gt;module M ... end&lt;/code&gt; 外で）、適当な変数に &lt;code&gt;Foo&lt;/code&gt; をセットしてみますと:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight ocaml"&gt;&lt;code&gt;&lt;span class="o"&gt;#&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Foo&lt;/span&gt;&lt;span class="p"&gt;;;&lt;/span&gt;
&lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Unbound&lt;/span&gt; &lt;span class="n"&gt;constructor&lt;/span&gt; &lt;span class="nc"&gt;Foo&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;コンストラクタ &lt;code&gt;Foo&lt;/code&gt; はモジュール &lt;code&gt;M&lt;/code&gt; 以下の名前空間にあるので失敗します。なので、 &lt;code&gt;Foo&lt;/code&gt; にモジュール &lt;code&gt;M&lt;/code&gt; を修飾してやればコンパイルにパスします（または &lt;code&gt;open M&lt;/code&gt; でもいいですが、それだと名前空間を汚すのでここでは置いときます）:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight ocaml"&gt;&lt;code&gt;&lt;span class="o"&gt;#&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;M&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Foo&lt;/span&gt;&lt;span class="p"&gt;;;&lt;/span&gt;
&lt;span class="k"&gt;val&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nn"&gt;M&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;M&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Foo&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;しかし &lt;code&gt;Foo&lt;/code&gt; が一箇所のみならこれでいいんですが、式中に何度も現れるといちいち修飾するのが面倒です。だったら、あらかじめ &lt;code&gt;x&lt;/code&gt; の型を &lt;code&gt;M.t&lt;/code&gt; に指定しておけばなんとかなりそうですよね。こうとか:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight ocaml"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nn"&gt;M&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;これなら右辺の式で &lt;code&gt;Foo&lt;/code&gt;, &lt;code&gt;Bar&lt;/code&gt;, &lt;code&gt;Baz&lt;/code&gt; が使えそうです。するとどうなるか:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight ocaml"&gt;&lt;code&gt;&lt;span class="o"&gt;#&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nn"&gt;M&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Foo&lt;/span&gt;&lt;span class="p"&gt;;;&lt;/span&gt;
&lt;span class="nc"&gt;Warning&lt;/span&gt; &lt;span class="mi"&gt;40&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Foo&lt;/span&gt; &lt;span class="n"&gt;was&lt;/span&gt; &lt;span class="n"&gt;selected&lt;/span&gt; &lt;span class="n"&gt;from&lt;/span&gt; &lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="nn"&gt;M&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;span class="nc"&gt;It&lt;/span&gt; &lt;span class="n"&gt;is&lt;/span&gt; &lt;span class="n"&gt;not&lt;/span&gt; &lt;span class="n"&gt;visible&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;current&lt;/span&gt; &lt;span class="n"&gt;scope&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;will&lt;/span&gt; &lt;span class="n"&gt;not&lt;/span&gt; 
&lt;span class="n"&gt;be&lt;/span&gt; &lt;span class="n"&gt;selected&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;becomes&lt;/span&gt; &lt;span class="n"&gt;unknown&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;span class="k"&gt;val&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nn"&gt;M&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;M&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Foo&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;おっと、警告 40 はここで出るんですね。「 &lt;code&gt;x&lt;/code&gt; は &lt;code&gt;M.t&lt;/code&gt; だと宣言してるんだから、 &lt;code&gt;Foo&lt;/code&gt; が &lt;code&gt;M.Foo&lt;/code&gt; なのは自明でしょ」と言いたくなりますが、それは利便性を優先したいユーザーの理屈であって、コンパイラはコンパイラで問題を把握しています。「べっ、別にあんたの指定した型を信用してないわけじゃないんだからねっ！ ただ、 &lt;code&gt;Foo&lt;/code&gt; がスコープ内に見当たらなくって、あんたの指定した型から仕方なく選んで……そ、そう、仕方なくよっ！」みたいな。「スコープ内に見当たらない」から &lt;strong&gt;「ちゃんと名前空間を指定せい」&lt;/strong&gt; というのがこの警告の趣旨なんでしょうね。……多分。&lt;/p&gt;

&lt;p&gt;私は当初この警告も指定していたのですが、修正がめんどくさくなって止めました。自分のコードでは、この警告を無視しても致命的な問題はなさそうだったし。まあ、もしかしたら私がこの警告の重要性を理解しないばかちんであるだけかもしれませんが。&lt;/p&gt;

&lt;p&gt;ちなみに、この警告を修正しようとして &lt;code&gt;open&lt;/code&gt; するモジュールを増やすのは逆効果です。修正するなら局所的な &lt;code&gt;open&lt;/code&gt; を使うか（ &lt;code&gt;let open ... in&lt;/code&gt; てやつ）、素直にモジュール名を修飾しとくのがよさげです。ちなみにフィールド名を修飾するには &lt;code&gt;data.Module.field&lt;/code&gt; と書きますが、実は &lt;code&gt;Module.(data.field)&lt;/code&gt; とも書けるんですよ。知ってました？（ドヤァ&lt;/p&gt;

&lt;h2&gt;
  
  
  【そんな定義で大丈夫か？】警告 42【大丈夫だ、問題ない】
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;-- Disambiguated constructor or label name.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;と書くとエラい人の格言みたいですね。どうでもいいって？&lt;/p&gt;

&lt;p&gt;この警告は、一応型は決定できるけれども、同一の名前空間に同名のコンストラクタが存在する場合、または同名のフィールドが複数のレコードに存在する場合に出ます。警告 40 と同じく、ラベル名とはレコードのフィールド名のようです。&lt;/p&gt;

&lt;p&gt;ここではレコードを例に挙げます。まったく同じフィールド名を持つレコードがいくつかあったとして（無理矢理に見えますけど実際そうしたい場合もあるんですよ！ ソースは俺）:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type t = {
  x : int;
  y : int;
}

type u = {
  x : int;
  y : int;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;型を指定した上でフィールドを参照すると警告されます:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# let x (r:t) = r.x
Warning 42: this use of x required disambiguation.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;code&gt;(r:t)&lt;/code&gt; と型を指定しているのでコンパイルは通してくれますが（警告 40 が同時に指摘される場合もあります）、フィールド &lt;code&gt;x&lt;/code&gt; は複数のレコード &lt;code&gt;t&lt;/code&gt; &lt;code&gt;u&lt;/code&gt; に定義されていますよ、という警告です。試しにここから型指定を外してみますと:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# let x r = r.x
Warning 41: x belongs to several types: u t
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;警告 41 が出て、複数の候補があると指摘されます。警告なしの設定ではコンパイル時に適当に型が選択されるわけですが、モテない男は目の前にチャンスが複数ぶら下がっていても選べない……ってやかましいわ！&lt;/p&gt;

&lt;p&gt;……さて警告 42 を避ける方法ですが、&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;適当な接頭辞をつけて名前の重複を避ける（ &lt;code&gt;t_x&lt;/code&gt; &lt;code&gt;u_x&lt;/code&gt; など）か、&lt;/li&gt;
&lt;li&gt;異なる名前空間（モジュール）に振り分ける&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;のどちらかのようです。「いちいち型ごとにモジュールを作るの？」と訝しんだあなた、&lt;a href="http://d.hatena.ne.jp/camlspotter/20121216/1355686499"&gt; 1 モジュール 1 データ型スタイル&lt;/a&gt;というやり方もありますよ。 OCaml のことだし高尚な技法じゃないの？と怖がる必要はなく、「 OCaml じゃこう書いとけばメンテ楽じゃね？」程度の流行と捉えておけばいいんじゃねと思います。開発手法の流行り廃りってそんなもんでしょ？&lt;/p&gt;

&lt;p&gt;ただし型名は修飾できないので（ &lt;code&gt;r.t.x&lt;/code&gt; とか書けない）、いくらかコードが膨らむと気軽に修正できなかったりするんですよね。実際私のコードでは時間的・能力的に修正できていません（ビギナーですからね！）。ので、現在私は無視しています。新規にプロジェクトを始めるときは有効にしておいてもいいかもしれませんね。&lt;/p&gt;

&lt;h2&gt;
  
  
  【お兄ちゃんどいて！】警告 44, 45【そいつ使えない！】
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;open&lt;/code&gt; したモジュールが既存の識別子（警告 44 ）またはコンストラクタやラベル（警告 45 ）を上書きしてしまう（重複する）場合に警告されます。例によって実用的に何の意味もない次の例では、 &lt;code&gt;open&lt;/code&gt; した  &lt;code&gt;List.length&lt;/code&gt; によって &lt;code&gt;length&lt;/code&gt; が上書きされてしまいます。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight ocaml"&gt;&lt;code&gt;&lt;span class="o"&gt;#&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;rec&lt;/span&gt; &lt;span class="n"&gt;length&lt;/span&gt; &lt;span class="n"&gt;l&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;open&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt;
    &lt;span class="n"&gt;length&lt;/span&gt; &lt;span class="n"&gt;l&lt;/span&gt; &lt;span class="c"&gt;(* List.length が優先される *)&lt;/span&gt;
    &lt;span class="p"&gt;;;&lt;/span&gt;
&lt;span class="nc"&gt;Warning&lt;/span&gt; &lt;span class="mi"&gt;44&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;this&lt;/span&gt; &lt;span class="k"&gt;open&lt;/span&gt; &lt;span class="n"&gt;statement&lt;/span&gt; &lt;span class="n"&gt;shadows&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="n"&gt;identifier&lt;/span&gt; &lt;span class="n"&gt;length&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;which&lt;/span&gt; &lt;span class="n"&gt;is&lt;/span&gt; &lt;span class="n"&gt;later&lt;/span&gt; &lt;span class="n"&gt;used&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="o"&gt;#&lt;/span&gt; &lt;span class="n"&gt;length&lt;/span&gt; &lt;span class="bp"&gt;[]&lt;/span&gt;&lt;span class="p"&gt;;;&lt;/span&gt;
&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;この警告、ぱっと見役立ちそうでしょ？ Jane Street Core に依存している私の開発環境で有効にしてみますと、 &lt;code&gt;@&lt;/code&gt; 演算子を使っている箇所で引っかかります。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Warning 44: this open statement shadows the value identifier @ (which is later used)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;これは　Core で &lt;code&gt;@&lt;/code&gt; が上書きされているためで、 &lt;code&gt;a @ b&lt;/code&gt; と書いた箇所を &lt;code&gt;Core.Std.(@) a b&lt;/code&gt; と書き直せば修正できるのですが、今度は &lt;code&gt;|&amp;gt;&lt;/code&gt; が引っかかりました。まあ Core 自体が標準ライブラリ を上書きするライブラリですから仕方がないのかもしれません。めんどくさいんで私はこの警告を無効にしてます。ついでに &lt;a href="http://d.hatena.ne.jp/camlspotter/20130904/1378277465"&gt;OCaml 4.01.0 変更点の 「 &lt;code&gt;open&lt;/code&gt; が既存の名前を覆い隠す時に警告」の節&lt;/a&gt;も読んでみるといいと思います。&lt;/p&gt;

&lt;p&gt;さて、以上は 44 の話です。 45 ではコンストラクタとラベルが対象です。あるモジュールで、私はこのような型を定義しました。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight ocaml"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;my_result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nc"&gt;Success&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nc"&gt;Failure&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="n"&gt;my_error&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;code&gt;Success&lt;/code&gt; と &lt;code&gt;Failure&lt;/code&gt; 、結果を示す型では使いたくなる名前です。ところが &lt;code&gt;Failure&lt;/code&gt; は標準ライブラリで &lt;code&gt;Failure of string&lt;/code&gt; と定義されているため、このモジュールを &lt;code&gt;open&lt;/code&gt; すると警告 45 に引っかかります。&lt;/p&gt;

&lt;p&gt;一応、 &lt;code&gt;Failure&lt;/code&gt; を使っている箇所を &lt;code&gt;モジュール名.Failure&lt;/code&gt; と書き換えれば修正できます。しかしそうなると、 &lt;code&gt;open&lt;/code&gt; の利便性を捨ててモジュール名をあちこち修飾して回るか、 &lt;code&gt;MySuccess&lt;/code&gt; とか &lt;code&gt;MyFailure&lt;/code&gt; などの適当な接頭辞をつけて衝突を回避するか……めんどくさいんで私はこの警告を無効にしてます。が、依存するライブラリに影響がなければ有効にするのもいいのかもしれません。私はまだそこまで判断できませんので、一度試してみてはいかがでしょうか。&lt;/p&gt;

</description>
      <category>ocaml</category>
    </item>
    <item>
      <title>OPAM パッケージ化のススメ</title>
      <dc:creator>SUZUKI Tetsuya</dc:creator>
      <pubDate>Thu, 23 Jan 2020 16:16:26 +0000</pubDate>
      <link>https://dev.to/szktty/opam-3383</link>
      <guid>https://dev.to/szktty/opam-3383</guid>
      <description>&lt;p&gt;※この記事は 2016年06月03日 に Qiita に投稿したものです。&lt;/p&gt;




&lt;p&gt;OCaml を使い慣れてくると、そのうち依存するライブラリのバージョンの管理に悩まされるときが来ると思います。 OCaml のライブラリは依存するライブラリが多くて、 OCaml またはライブラリのバージョンを上げたらビルドできなくなったというトラブルが少なくないかと思われます。私も何度か困りました。 &lt;a href="https://opam.ocaml.org/packages/core/core.113.33.03/"&gt;core&lt;/a&gt; とか見てください。一体いくつのライブラリに依存してるんですか。まあ core も含めてほとんどが Jane Street 製ですけど。&lt;/p&gt;

&lt;p&gt;そこで OPAM パッケージ化の勧めです。大半の OCaml ユーザーは OPAM でパッケージ管理を行っているかと思います。パッケージ化というと敷居が高い気がしますが、そう難しくもありませんでした。 &lt;code&gt;opam install&lt;/code&gt; を何度も実行して依存するライブラリをインストールしてはバージョン違いによるビルドエラーに悩む日々とサヨナラです。偉そうに言ってる私もビルドエラーの原因探しで困っていたところに「 OPAM で管理しなよ」と言われて今に至ります。&lt;/p&gt;

&lt;p&gt;さらに詳しくは &lt;a href="https://opam.ocaml.org/doc/Manual.html"&gt;OPAM のマニュアル&lt;/a&gt;を参照してください。英語しかないけどがんばって。フランス語で書かれるよりましです。&lt;/p&gt;

&lt;h2&gt;
  
  
  OPAM パッケージ化のメリット
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;OCaml のバージョンを依存するライブラリのバージョンを指定できます。&lt;/li&gt;
&lt;li&gt;依存するライブラリをインストールしてくれます。&lt;/li&gt;
&lt;li&gt;ローカルのみの OPAM パッケージとして使えます。&lt;/li&gt;
&lt;li&gt;インストールは &lt;code&gt;opam install&lt;/code&gt; だけで OK です。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;OPAM パッケージ化は、ファイルを一つ書けばいいだけで簡単です。ローコストでこれだけのメリットがあって損はありません。偉そうに言っている私も（ry&lt;/p&gt;

&lt;h2&gt;
  
  
  サンプルプログラム
&lt;/h2&gt;

&lt;p&gt;サンプルとして &lt;a href="https://github.com/szktty/ocalc"&gt;RPN 電卓を作ってみました。&lt;/a&gt;あまり簡単な例を出してもかえって頭に入ってこないかなと思いまして、自分で使ってみようと思ってそこそこ作ってあります。ときどき Python の対話モードを電卓代わりに使っているんですが + を何度も書くのが面倒で、数字だけ並べて一気に足せると楽そうです。こんな感じ。 +! でスタック内の数値を全部足します。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ ocalc
Try "h" for more information.
&amp;gt;&amp;gt;&amp;gt; 1 2 3 4 5 6 7 8 9 10 +!
55
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;先にインストールの方法について触れときます。このリポジトリをダウンロードしたら、トップディレクトリで次のコマンドを実行するとインストールできます。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ opam pin add ocalc .
$ opam install ocalc
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;上のコマンドが、ローカルな OPAM パッケージをローカル OPAM リポジトリに追加します。追加したら、以降はいつもの &lt;code&gt;opam install&lt;/code&gt; でパッケージをビルド、インストールできるようになります。アンインストールは &lt;code&gt;opam uninstall ocalc&lt;/code&gt; です。&lt;/p&gt;

&lt;h2&gt;
  
  
  OPAM パッケージを作る
&lt;/h2&gt;

&lt;p&gt;OPAM パッケージ化は簡単です。 &lt;a href="https://github.com/szktty/ocalc/blob/develop/opam"&gt;opam&lt;/a&gt; という名前のファイルを用意するだけです。これが中身です。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;opam-version: "1.2"
version: "1.0.0"
authors: "SUZUKI Tetsuya &amp;lt;tetsuya.suzuki@gmail.com&amp;gt;"
maintainer: "SUZUKI Tetsuya &amp;lt;tetsuya.suzuki@gmail.com&amp;gt;"
homepage: "https://github.com/szktty/ocalc"
bug-reports: "https://github.com/szktty/ocalc/issues"
dev-repo: "https://github.com/szktty/ocalc.git"
license: "Apache License, Version 2.0"
build: [
  [ "omake" "PREFIX=%{prefix}%" ]
]
install: [
  [ "omake" "install" "PREFIX=%{prefix}%" ]
]
remove: [
  [ "omake" "uninstall" "PREFIX=%{prefix}%" ]
]
depends: [
  "omake" { = "0.9.8.6-0.rc1" }
  "menhir" { = "20160504" }
  "spotlib" { = "3.1.0" }
]
available: [
  ocaml-version &amp;gt;= "4.03.0"
]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;このファイルのフォーマットは YAML に見えなくもないですが OPAM 専用です。見た感じ適当にやってもどうにかなるでしょう。&lt;/p&gt;

&lt;p&gt;&lt;code&gt;license&lt;/code&gt; までの前半は特に説明不要かと思います。それ以降の項目はビルド処理と依存の指定です。 &lt;code&gt;available&lt;/code&gt; で OCaml のバージョンを、 &lt;code&gt;depends&lt;/code&gt; で依存ライブラリやツール＋バージョンを指定します（バージョン未指定でもOKです）。 ocalc は次のライブラリとツールに依存していますので、それを &lt;code&gt;depends&lt;/code&gt; に記述しています。&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;OMake: ビルドツール&lt;/li&gt;
&lt;li&gt;Menhir: いわゆる yacc&lt;/li&gt;
&lt;li&gt;Spotlib: コンパクトな便利ライブラリ&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;特に明確な方針があるわけでもないんですが、 OCaml のバージョンは 4.03.0 「以降」、依存ライブラリはバージョンを「固定」しています。 OCaml 以外は仕様変更で ocalc がビルドできなくなる可能性が高いので固定しておきます。&lt;/p&gt;

&lt;p&gt;&lt;code&gt;build&lt;/code&gt;, &lt;code&gt;install&lt;/code&gt;, &lt;code&gt;remove&lt;/code&gt; の項目は、それぞれ OPAM から呼ばれたときに実行されるコマンドのリストです。 &lt;code&gt;build&lt;/code&gt; と &lt;code&gt;install&lt;/code&gt; は &lt;code&gt;opam install&lt;/code&gt; 時に呼ばれ、 &lt;code&gt;remove&lt;/code&gt; は &lt;code&gt;opam uninstall&lt;/code&gt; 時に呼ばれます。基本的に OMake を呼ぶだけですが、 &lt;code&gt;%{prefix}&lt;/code&gt; と書くとそこに OPAM のパスが置換されるので、それを OMake に渡しています。 OMakefile には PREFIX で指定されたパスにプログラムをインストールする設定を書いてあります。&lt;/p&gt;

&lt;p&gt;&lt;code&gt;build&lt;/code&gt;, &lt;code&gt;install&lt;/code&gt;, &lt;code&gt;remove&lt;/code&gt; は OPAM から呼ばれるだけの項目なので、実際にインストールやアンインストールを行う必要はありません。システムにインストールしたくないアプリケーションでも、ここを空にしておけば OPAM のバージョン依存管理の恩恵を受けられます。&lt;/p&gt;

&lt;h2&gt;
  
  
  注意点
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;OPAM に登録されているライブラリは、依存するライブラリのバージョンが指定されていないことがあります。 &lt;del&gt;例えば &lt;a href="https://opam.ocaml.org/packages/core/core.113.33.03/"&gt;core&lt;/a&gt; はこれだけ依存ライブラリが指定されていますが、 OCaml のバージョンが指定されていません。最新版の OCaml で過去の core を使ったり、あるいは過去の OCaml で最新の core を使おうとすると、他ライブラリで指定される OCaml のバージョンと競合する可能性があります&lt;/del&gt; (現在は OCaml のバージョンが指定されています) 。既存のプロジェクトを OPAM パッケージ化する場合、できるなら OCaml とライブラリをすべて最新版に保つのがいいです。&lt;/li&gt;
&lt;li&gt;もちろん OPAM 自身もバージョンが上がると仕様が変わります。当然設定ファイルの内容も変わったりするので、常に最新版を使いましょう。&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ocaml</category>
    </item>
    <item>
      <title>型安全の夢を一行で打ち砕く黒魔術入門</title>
      <dc:creator>SUZUKI Tetsuya</dc:creator>
      <pubDate>Thu, 23 Jan 2020 16:13:43 +0000</pubDate>
      <link>https://dev.to/szktty/-4h2m</link>
      <guid>https://dev.to/szktty/-4h2m</guid>
      <description>&lt;p&gt;※この記事は 2018年01月13日 に Qiita に投稿したものです。&lt;/p&gt;

&lt;p&gt;※Reason 向けですが OCaml とほぼ共通します。&lt;/p&gt;




&lt;p&gt;ドキュメントを眺めていて、&lt;a href="https://reasonml.github.io/docs/ja/type.html"&gt;こんな記述を見つけました。&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;型システムは完全に「安全」です。 これは、コードがコンパイルされている限り、すべての型に誤りがないことが保証されることを意味します。 従来のベストエフォートな型システムでは、例えば「Integer は決して null にならない」と言っていたとしても、言っているだけで、本当に決して null にならないということではありません。 それとは対照に、純粋な Reason プログラムは null のバグはありません。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;私は型理論に明るくないので「型の完全性」が何を示すのかはわかりませんが、型安全の抜け道は知ってます。私だけでなく、 OCaml ユーザーならわかるでしょう。&lt;/p&gt;

&lt;p&gt;それは &lt;a href="https://reasonml.github.io/api/Obj.html"&gt;Obj.magic&lt;/a&gt; という関数です。この関数の型はこう定義されています。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let magic: 'a =&amp;gt; 'b;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;これを見て笑った人は、この記事を読む必要はありません。もうわかったはずです。&lt;/p&gt;

&lt;p&gt;なんだこりゃ？と思った方は、一つ冷静になって考えてみてください。この関数は、 &lt;strong&gt;任意の型 'a を、任意の型 'b に変換&lt;/strong&gt; します。当然ながら、 'a と 'b は同じ型である必要はありません。 'a が int で 'b が bool でもいいわけです。&lt;/p&gt;

&lt;p&gt;この型の関数の実装を考えてみてください。処理内容はどうでもいいものとします。関数の型が &lt;code&gt;'a =&amp;gt; 'b&lt;/code&gt; になれば OK です。&lt;/p&gt;

&lt;p&gt;例えば、 int を bool に変換する関数は簡単に書けるでしょう。処理内容はどうでもいいので、単に true を返すだけでも構いません。次に、 int を任意の型 'b に変換する関数はどうでしょうか。もちろん 'b は関数が呼び出される文脈によって変わります。 'b は bool かもしれませんし、 string かもしれません。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let f = (value: int) : 'b =&amp;gt; {
  /* どうする？ */
};
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;何か思いつきます？ 無理じゃないですか？ 任意の型を戻り値にするとはどうすればいいのか。任意の型を生成するとは？ int 値を任意の値に変更する？ どうやって？&lt;/p&gt;

&lt;p&gt;Obj.magic はどうにかしちゃいます。型の上では任意の型 'a を任意の型 'b に変換します。ただし、 Obj.magic は何もしません。引数の値をそのまま戻り値にします。型だけが変わります。つまり、 int の値を string として扱えるようになります。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/* 見た目は文字列、中身は整数！ */
let f = (a: int) : string =&amp;gt; Obj.magic(a);

/* 文字列の長さを表示する */
Js.log(String.length(f(123)));
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;a href="https://reasonml.github.io/en/try.html"&gt;オンライン&lt;/a&gt;でこのコードを入力してみてください。出力には &lt;code&gt;undefined&lt;/code&gt; と表示されるはずです。&lt;/p&gt;

&lt;p&gt;出力される JavaScript のコードを見ればはっきりわかります。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Generated by BUCKLESCRIPT VERSION 1.9.2, PLEASE EDIT WITH CARE&lt;/span&gt;
&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;use strict&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;


&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;f&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="mi"&gt;123&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;exports&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;f&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;f&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="cm"&gt;/*  Not a pure module */&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;整数 &lt;code&gt;123&lt;/code&gt; は &lt;code&gt;length&lt;/code&gt; プロパティを持っていないので結果は &lt;code&gt;undefined&lt;/code&gt; です。 Reason の型検査をすり抜けてしまいました。ちなみに OCaml の出力だと &lt;code&gt;Obj.magic&lt;/code&gt; が残ります。元々 OCaml のライブラリの API なので。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight ocaml"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;Obj&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;magic&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Js&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;log&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;String&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="mi"&gt;123&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;code&gt;Obj.magic&lt;/code&gt; はどうしても使わなければならない場面があり、実際に &lt;a href="https://github.com/reasonml/reason-react/search?utf8=%E2%9C%93&amp;amp;q=obj.magic&amp;amp;type="&gt;ReasonReact&lt;/a&gt; でも使われています。普通は使いませんし推奨もしませんが、 &lt;code&gt;Obj.magic&lt;/code&gt; を使っているライブラリは型検査をすり抜けたバグを含む可能性がある、ということを頭の隅に置いておくと、いざというときにデバッグにかかる時間を削減できるかもしれません。&lt;/p&gt;

</description>
      <category>reason</category>
      <category>ocaml</category>
    </item>
    <item>
      <title>"type t" とは何か</title>
      <dc:creator>SUZUKI Tetsuya</dc:creator>
      <pubDate>Thu, 23 Jan 2020 16:11:05 +0000</pubDate>
      <link>https://dev.to/szktty/type-t-1c63</link>
      <guid>https://dev.to/szktty/type-t-1c63</guid>
      <description>&lt;p&gt;※この記事は 2018年01月12日 に Qiita に投稿したものです。&lt;/p&gt;

&lt;p&gt;※Reason 向けの内容ですが、 OCaml とも共通します。&lt;/p&gt;




&lt;p&gt;Reason で書かれたコードを見ていると、ところどころで &lt;code&gt;type t&lt;/code&gt; という一文字の型名を目にします。&lt;a href="https://github.com/reasonml/reason-react/blob/36135bfb8905e99fea24224947adb89af40ffed1/src/ReactEventRe.rei#L43"&gt;例えばこういうの&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;module Synthetic = {
  type tag;
  type t = synthetic(tag);
  ...
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;これは &lt;a href="http://d.hatena.ne.jp/camlspotter/20121216/1355686499"&gt;1モジュール1データ型主義&lt;/a&gt; という OCaml の一慣習から来ています（いると思われます）。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://reasonml.github.io/docs/en/record.html#record-types-are-found-by-field-name"&gt;Reason のドキュメントにレコード定義の一例があります。&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type person = {age: int, name: string};
type monster = {age: int, hasTentacles: bool};
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;どちらのレコードも &lt;code&gt;age&lt;/code&gt; という同名のフィールドを持ちます。 Reason のレコードは名前空間が独立しておらず共有されるため、型推論時の &lt;code&gt;person&lt;/code&gt; と &lt;code&gt;monster&lt;/code&gt; の区別はフィールド名の組み合わせで判断されます。レコードの生成時に &lt;code&gt;name&lt;/code&gt; フィールドがあれば &lt;code&gt;person&lt;/code&gt; 型、 &lt;code&gt;hasTentacles&lt;/code&gt; フィールドがあれば &lt;code&gt;monster&lt;/code&gt; 型と判断されます（&lt;a href="https://reasonml.github.io/docs/en/record.html#record-needs-an-explicit-definition"&gt;もちろん明示的にレコード型を指定することもできます&lt;/a&gt;）。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/* person */
let me = {age:100, name:"me"};

/* monster */
let me = {age:100, hasTentacles:true};
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;では、まったく同じフィールドを持つレコード型があったらどうでしょうか。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type person = {age:int, name:string};
type monster = {age:int, name:string};

/* どっちのレコード？ */
let me = {age:100, name:"me"};
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;特に型の指定がなければ、フィールド名では型を判断できません。このような場合、 Reason では最後に定義された型とされます。 &lt;code&gt;me&lt;/code&gt; は &lt;code&gt;monster&lt;/code&gt; 型です。&lt;/p&gt;

&lt;p&gt;ですので、次のように &lt;code&gt;person&lt;/code&gt; を引数に受け取る関数に &lt;code&gt;me&lt;/code&gt; を渡すと型エラーになります。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let me = {age: 100, name: "me"};

/* person 型の引数を取るだけで何もしない関数 */
let f = (who: person) =&amp;gt; ();

f(me);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;コンパイルエラー:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  13 │ let f = (who: person) =&amp;gt; ();
  14 │ 
  15 │ f(me);

  This has type:
    monster
  But somewhere wanted:
    person  
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;code&gt;me&lt;/code&gt; は &lt;code&gt;monster&lt;/code&gt; 型だと判断されました。この場合は &lt;code&gt;me&lt;/code&gt; の型を &lt;code&gt;person&lt;/code&gt; と明示的に指定すれば大丈夫です。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let me: person = {age: 100, name: "me"};
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;del&gt;OCaml だとフィールド名が重複すればコンパイル時に警告されます。 Reason の唯一の工夫のように見えますが、かえって落とし穴ができてしまった気もします。&lt;/del&gt;&lt;/p&gt;

&lt;p&gt;ただし、既存のレコードとフィールド名が重複していると警告 42 で注意されます。 (デフォルトの警告の設定では無効です)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   9 │ };
  10 │ 
  11 │ let me:person = {age: 100, name: "me"}; // ``age`` の部分がハイライトされる
  12 │ 
  13 │ let f = (who: person) =&amp;gt; ();

  this use of age required disambiguation
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;ここで元の問題に戻ります。以上の通りレコードは名前空間にならないので、フィールド名が重複する複数のレコードを定義する場合は、フィールド名に適当な接頭辞をつければ問題は回避できます。でも &lt;code&gt;person_age&lt;/code&gt; や &lt;code&gt;monster_age&lt;/code&gt; といちいちやるのはあまりかっこよろしくない。だからそれぞれのレコード型に専用のモジュールを用意すればフィールド名の重複を気にかけなくていい:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;module Person = {
  type t = {
    age: int,
    name: string
  };
};

module Monster = {
  type t = {
    age: int,
    name: string
  };
};
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;このときに使う型名が &lt;code&gt;t&lt;/code&gt; です（"type" の "t" かな？）。かつてのレコード &lt;code&gt;person&lt;/code&gt; と &lt;code&gt;monster&lt;/code&gt; はそれぞれ &lt;code&gt;Person.t&lt;/code&gt; と &lt;code&gt;Monster.t&lt;/code&gt; として定義されます。 &lt;code&gt;t&lt;/code&gt; とつく型は、そのモジュールの中心的なデータ型だとわかります。インターフェースファイルである &lt;code&gt;.rei&lt;/code&gt; と &lt;code&gt;t&lt;/code&gt; を探せば、 API のだいたいの意味が推測できます。&lt;/p&gt;

&lt;p&gt;以上です。 Reason は OCaml を丸ごと新しい文法で覆っただけなので、 OCaml の不便な点も、不便を解消するためのイディオムもそのまま引きずっています。改善すべき点は文法以外にもあるんじゃないですかね...&lt;/p&gt;

</description>
      <category>reason</category>
      <category>ocaml</category>
    </item>
    <item>
      <title>私的即席プラクティスパターン （※古い内容です）</title>
      <dc:creator>SUZUKI Tetsuya</dc:creator>
      <pubDate>Thu, 23 Jan 2020 16:05:21 +0000</pubDate>
      <link>https://dev.to/szktty/-1mna</link>
      <guid>https://dev.to/szktty/-1mna</guid>
      <description>&lt;p&gt;※この記事は 2015年12月25日 に Qiita に投稿したものです。&lt;/p&gt;

&lt;p&gt;※ Rust 1.4.0 時の内容でありかなり古く、 Rust 的に褒められた作法ではありません。消そうか残そうか迷いましたが、いまだそこそこ閲覧があり、こういう形で学習した人間もいるということで残しておきます。ご了承ください。&lt;/p&gt;




&lt;p&gt;Rust のコードを書いていて、個人的に躓きがちだった点をまとめてみました。あくまで私的な意見で、 Rust の公式的な作法ではありません。&lt;/p&gt;

&lt;p&gt;想定する Rust のバージョンは 1.4.0 stable です。 1.5.0 でも特に問題ないとは思いますがわかりません。また、 unstable な API には触れません。&lt;/p&gt;

&lt;h2&gt;
  
  
  方針
&lt;/h2&gt;

&lt;p&gt;これらの私的なパターンもしくは Tips の方針は、 &lt;strong&gt;「コードが汚かろうが無駄な処理が多かろうが、動けば正義」&lt;/strong&gt; です。&lt;/p&gt;

&lt;p&gt;Rust はリソース管理の複雑さと強い型付けによってコンパイルエラーが出る機会が多く、慣れないうちは修正方法すらわかりません。始めからすべての仕様を把握しようとすると、コンパイルエラーの修正でいっぱいいっぱいになって、トライ＆エラーどころじゃなくなると思います（ただ、エラーメッセージはかなり親切です）。そこで、まずはコンパイルエラーを最小限にして少しずつ慣れていこう、というスタンスです。そういう私も、きっと闇の軍団にコードレビューされたら葬られるようなコードを書いてると思います。&lt;/p&gt;

&lt;p&gt;最初から礼儀正しいコードを書きたい人にとっては害悪なだけかもしれません。まあ、それはそれで清く正しくコンパイルの闇に飲まれてみるのもありかなと思います。&lt;/p&gt;

&lt;h2&gt;
  
  
  基本的な型
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &amp;amp;str と String
&lt;/h3&gt;

&lt;p&gt;文字列を表す型は二つあります。 str と String です。 str がプリミティブな型で、 String は Rust 自身で実装されている型です。 どちらの型も相互変換が可能です。&lt;/p&gt;

&lt;p&gt;文字列型が二つもあるなんて面倒だなあと思いますが、積極的に使うのは String です。 str の方は、基本的に &amp;amp;str という借用の形で使います。&lt;/p&gt;

&lt;p&gt;プリミティブな型である str は、普通使わないし使えないと考えていいと思います。 Rust のコンパイラは、コンパイル時にサイズが決定できない型を変数の型に指定するとエラーにします。で、 str もコンパイル時にサイズを決定できない型です。この意味がまだわからなくても大丈夫です。とにかく、次のような変数は定義できません。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let s: str;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;しかし、 &amp;amp;str という借用の型であればコンパイル時にサイズを決定でき、変数の型として使えます。とにかくそういうものなのです。&lt;/p&gt;

&lt;p&gt;それで &amp;amp;str がどこで使われるのかと言うと、一つは文字列リテラルです。文字列リテラルの型は &amp;amp;'static str で、 'static は生存期間を示しますが、それはさておき &amp;amp;str です。これ以外で str を生成する機会はまずないと考えていいと思います。文字列を生成したり編集したりする場合は String を使います。&lt;/p&gt;

&lt;p&gt;String は、動的に生成できる可変の UTF-8 の文字列です。この文字列は動的にサイズを伸縮でき、内容を変更できます。コンパイル時にサイズを決定できるため、変数の型に指定できます。とりあえずの理解は「 String を使え」でいいと思います。&lt;/p&gt;

&lt;p&gt;で、自分から文字列を生成・操作するなら String でいいんですが、 &amp;amp;str は引数や戻り値にたびたび登場し、 String への変換を行う必要も出てきます。また、文字列リテラルを String 型の変数にセットしたい場合も、 &amp;amp;str から String の変換が必要です。&lt;/p&gt;

&lt;p&gt;&amp;amp;str から String の変換は to_string() メソッドで可能です（ API に ToString トレイト実装済みと書かれていれば使えます）。人のコードでやたらと見かける to_string() は、それだけ &amp;amp;str が引数や戻り値として使われていることを示しています。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let s: String = "hello".to_string()
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;--&lt;/p&gt;

&lt;p&gt;ただ、 to_string() はゼロコストというわけにはいきません。具体的には、&lt;a href="https://doc.rust-lang.org/src/collections/string.rs.html#1495"&gt;フォーマット化によって文字列化するために、メモリーアロケーション＋フォーマット化のコストがかかります。&lt;/a&gt; &amp;amp;str に限って言えば、 to_owned() を使えば&lt;a href="https://doc.rust-lang.org/src/collections/borrow.rs.html#56"&gt;メモリーアロケーションのみで済む&lt;/a&gt;ので、余裕があれば頭の隅にでも置いておくといいと思います。&lt;/p&gt;

&lt;p&gt;--&lt;/p&gt;

&lt;p&gt;「 String を使え」と言っておきながら &amp;amp;str が頻出するのですが、 &amp;amp;str を使うのには理由があります。ただ、慣れないうちは &amp;amp;str と String の関係を理解できるまで String で済ませれておけばいいんじゃないかと思います。とにかく &amp;amp;str を受け取る場面では to_string で String に変換することにして、 &amp;amp;str と String について理解する労力を他に回せばいいと思うのですよ。&lt;/p&gt;

&lt;p&gt;で、次の問題は、引数に &amp;amp;str を受け取る関数はあるけど String を受け取る関数がない状況です。例えば String がいきなりそれです。文字列を追加するメソッドで、 &amp;amp;str を受け取る push_str() はありますが、 String を受け取って欲しい push_string() はありません。「オメー何で自分を使わねえんだよ」と当初思いました。&lt;/p&gt;

&lt;p&gt;そういう場合は String を &amp;amp;str に変換すればいい、とだいぶ後になって理解しましたが、その変換方法がまたトリッキーで、「  String の借用 = &amp;amp;str 」の関係が成り立ちます。つまり、 String の型の変数の先頭に &amp;amp; をつければ &amp;amp;str の型の引数に渡せます。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fn print_str(s: &amp;amp;str) {
    println!("str = {}", s)
}

fn main() {
    print_str("hello");
    let world: String = "world".to_string();
    print_str(&amp;amp;world);
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;まとめます。相互変換は次の方法で行います。&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&amp;amp;str -&amp;gt; String の変換は to_string() で行う&lt;/li&gt;
&lt;li&gt;String -&amp;gt; &amp;amp;str の変換は &amp;amp; をつける&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&amp;amp;str と String の使い分けの方針は、&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;引数として受け取る文字列は &amp;amp;str&lt;/li&gt;
&lt;li&gt;構造体のフィールドとする文字列は String&lt;/li&gt;
&lt;li&gt;戻り値にする文字列は String&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;と大雑把に捉えておいていいのではないかと思います。混乱しそうであれば、すべて String でもいいのではないかと思います。&lt;/p&gt;

&lt;h3&gt;
  
  
  &amp;amp;'static str
&lt;/h3&gt;

&lt;p&gt;文字列リテラルの型です。 'static は特殊な生存期間で、静的にメモリが確保される文字列です。プログラムの実行中はずっと生存します。&lt;/p&gt;

&lt;h3&gt;
  
  
  Vec&amp;lt;T&amp;gt;
&lt;/h3&gt;

&lt;p&gt;リストです。 T にはリストの要素の型が入ります。&lt;/p&gt;

&lt;p&gt;Vec を使うのに何らかのモジュールをインポートする必要はありません。&lt;/p&gt;

&lt;h3&gt;
  
  
  HashMap&amp;lt;K, V&amp;gt;
&lt;/h3&gt;

&lt;p&gt;キーがハッシュ値であるマップです。 K がキーの型で、 V が値の型です。HashMap を使うには、  std::collections::HashMap モジュールをインポートする必要があります。&lt;/p&gt;

&lt;p&gt;ハッシュ値を算出できなければならないため、キーの型は Eq トレイトと Hash トレイトを実装する必要があります。これは型の定義時に &lt;code&gt;#[derive(PartialEq, Eq, Hash)]&lt;/code&gt; を指定すれば簡単です。 Hash トレイトを適用できない型が含まれる場合は自前で実装しなければなりませんが、慣れないうちはハードルが高いかもしれません。その場合はハッシュ値を算出できる他の型をキーにすることを検討してはどうでしょうか。&lt;/p&gt;

&lt;h3&gt;
  
  
  HashSet&amp;lt;K, V&amp;gt;
&lt;/h3&gt;

&lt;p&gt;要素が重複しない集合です。重複の検査にハッシュ値を使うため、 HashMap と同様に Eq トレイトと Hash トレイトを実装する必要があります。 HashSet を使うには、  std::collections:: HashSet モジュールをインポートする必要があります。&lt;/p&gt;

&lt;h3&gt;
  
  
  Option&amp;lt;T&amp;gt;
&lt;/h3&gt;

&lt;p&gt;「あるのかないのか」を表す型です。何に使うんだ？と言うと、他の言語で「値がない」ことを nil や null で表していた処理を None と Some(T) に置き換えればいいと思います。&lt;/p&gt;

&lt;h3&gt;
  
  
  Result&amp;lt;T, E&amp;gt;
&lt;/h3&gt;

&lt;p&gt;処理の成否を表す型です。成功時の値の型が T 、失敗時の値の型が E です。 Rust には捕捉可能な例外処理機構はなく、エラーの可能性を示したいときはこの型を使います（ panic! マクロがエラーメッセージの表示に使えますが、表示後にプログラムが終了します）。積極的に使っていくべきです（「あ、この処理は引数の値次第でエラーにすべきだな」と思ったときが使いどころです）。 try! マクロと組み合わせて使うと便利です。&lt;/p&gt;

&lt;p&gt;ちなみに、同名の型が std::io モジュールにもあります。こちらの Result は、入出力に関するエラー io::Error をエラー値に持つ Result として定義されています。簡単に言うと、 io モジュールの関数の戻り値に毎度 Result&amp;lt;T, io::Error&amp;gt; と書くのが面倒になった（のと、エラー値の型を隠蔽したい）ので、一つの型として定義しておいた、と考えていいと思います。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type Result&amp;lt;T&amp;gt; = Result&amp;lt;T, std::io::Error&amp;gt;;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  Box&amp;lt;T&amp;gt;
&lt;/h3&gt;

&lt;p&gt;任意のデータ型 T の値をラップする型です。一体何の役に立つのかと言うと、再帰的な構造体や列挙体の定義に使います。こんな感じです。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#[derive(Clone)]
struct Employee {
    name: String,
    boss: Box&amp;lt;Option&amp;lt;Employee&amp;gt;&amp;gt;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;このオブジェクトを生成する例:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Employee { name: "John".to_string(), boss: Box::new(None) }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;この構造体では Option を Box でラップしていますが、ラップをしないと生成できなくなってしまうからですね。 None の位置に何を入れるか考えてみるとわかると思います。&lt;/p&gt;

&lt;p&gt;Box でラップされた中身を取り出すには、式の前に &lt;code&gt;*&lt;/code&gt; をつけます。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let jack = Employee { name: "Jack".to_string(), boss: Box::new(None) };
let john = Employee { name: "John".to_string(), boss: Box::new(Some(jack)) };
match *john.boss {
    None =&amp;gt; println!("boss is none"),
    Some(ref boss) =&amp;gt; println!("boss is {}", boss.name)
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  よく使うマクロ
&lt;/h2&gt;

&lt;h3&gt;
  
  
  print!, println!
&lt;/h3&gt;

&lt;p&gt;標準出力にフォーマットしたテキストを出力します。とりあえず覚えておくといいフォーマットは "{}" です。こんな感じで使います。当面は "{}" だけ覚えてればなんとかなります。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let p = "hello";
println!("data = {}", p)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;ただし、これで出力できる値には制限があり、任意のすべての値を出力できるわけではありません。コンパイル時に Display がどうのというエラーが出た場合は、 String に変換するメソッドを実装するなどして、 String に変換した値をフォーマットに指定すれば大丈夫です。&lt;/p&gt;

&lt;h3&gt;
  
  
  format!
&lt;/h3&gt;

&lt;p&gt;引数は print! と同じですが、こちらはフォーマットしたテキストを String で返します。他の言語で言う sprintf です。文字列の結合代わりに使うのも便利です。&lt;/p&gt;

&lt;h3&gt;
  
  
  write!, writeln!
&lt;/h3&gt;

&lt;p&gt;これも print! と同じくテキストをフォーマットします。ただし print! と違って出力先はバッファです。具体的には std::io::Write トレイトを実装したオブジェクトです。わかりやすい例は、文字列バッファである String です。 Vec も対応しています。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;use std::fmt::Write;

fn main() {
    let mut buf = String::new();
    write!(buf, "hello, ");
    write!(buf, "world!");
    println!("formatted: {}", buf);
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;なお、 write! は戻り値が Result&amp;lt;usize&amp;gt; です。上記のコードのように戻り値を処理しない場合は、コンパイラの設定次第で警告が出ます。&lt;/p&gt;

&lt;h3&gt;
  
  
  panic!
&lt;/h3&gt;

&lt;p&gt;回復不能なエラーを発生させます。このエラーは捕捉できず、プログラムはエラーメッセージを表示して終了します。エラーメッセージは、 print! と同様のフォーマットで指定します。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;panic!("error")
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  unimplemented!
&lt;/h3&gt;

&lt;p&gt;"not yet implemented" というメッセージを表示する panic! です。未実装の処理を後回しにしたいときに使ってもいいし、使わなくてもです。使う場合は、引数なしでこのように呼びます。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;unimplemented!()
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  unreachable!
&lt;/h3&gt;

&lt;p&gt;"internal error: entered unreachable code" という、到達不可能を示すメッセージを表示する panic! です。到達不可能のはずの箇所で使ってもいいし、使わなくてもいいです。&lt;/p&gt;

&lt;p&gt;このマクロの引数は print!/format! と同じか、 unimplemented! と同様に引数なしでも構いません。フォーマットを与えた場合は、上記のメッセージに続けて表示されます。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c"&gt;// thread '&amp;lt;main&amp;gt;' panicked at 'internal error: entered unreachable code: test', &amp;lt;anon&amp;gt;:3&lt;/span&gt;
&lt;span class="nd"&gt;unreachable!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"test"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  try!
&lt;/h3&gt;

&lt;p&gt;Result 型の値に対して使うマクロです。値が Err であれば、それを戻り値として関数から脱出し、 Ok であれば、 Ok が保持する値を返します。何やら複雑そうですが、 Result がエラーを示したら関数を終了したい、そうでなければ処理を続けたい、という状況は間々あります。その度にいちいち match で&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let value = match exp {
   Err(e) =&amp;gt; return Err(e),
   Ok(v) =&amp;gt; v
};
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;と書くのは面倒です。 try! を使うと、上のコードはこう書けます。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let value = try!(exp);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;このマクロのポイントは return で、関数では「現在の関数から脱出する処理」を実装できません。 Result と併用すると、エラー処理を書きやすくなるでしょう。&lt;/p&gt;

&lt;p&gt;ちなみに、 Option に対して同等の処理を行うマクロはないようです。もちろん自分で定義するのは自由ですが、あったらあったで、意外と使う機会があるようでないんじゃないかと思います。参考までに、 None であれば戻り値を None として関数を脱出するマクロの実装例を挙げておきます。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;macro_rules! expect {
    ($e:expr) =&amp;gt; ({
        use std::option::Option::{Some, None};

        match $e {
            Some(e) =&amp;gt; e,
            None =&amp;gt; return None,
        }
    })
}

fn test() -&amp;gt; Option&amp;lt;String&amp;gt; {
    let opt1: Option&amp;lt;String&amp;gt; = Some("hello".to_string());
    let opt2: Option&amp;lt;String&amp;gt; = None;
    let s = expect!(opt1);
    println!("opt1 = {}", s);

    let s = expect!(opt2);
    // 実行されない
    println!("opt2 = {}", s);

    None
}

fn main() {
    let _ = test();
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  vec!
&lt;/h3&gt;

&lt;p&gt;任意の数の式の並びから Vec オブジェクトを生成するマクロです。文章だとわかりにくいですが、要はこういう使い方をします。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// 要素が 1, 2 , 3 である Vec オブジェクトを生成する
let x: Vec&amp;lt;u32&amp;gt; = vec![1, 2, 3];
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;このマクロの引数は中括弧 [..] で囲むので注意です。&lt;/p&gt;

&lt;h3&gt;
  
  
  assert!, assert_eq!
&lt;/h3&gt;

&lt;p&gt;アサーションです。引数の値が　false であれば panic を発生させます。&lt;/p&gt;

&lt;h3&gt;
  
  
  debug_assert!, debug_assert_eq!
&lt;/h3&gt;

&lt;p&gt;こちらもアサーションですが、コンパイルオプションに &lt;code&gt;-C debug-assertions&lt;/code&gt; を指定したときにのみ有効になります。&lt;/p&gt;

&lt;h2&gt;
  
  
  コーディングスタイル
&lt;/h2&gt;

&lt;h3&gt;
  
  
  一度に 5 行以上書かない
&lt;/h3&gt;

&lt;p&gt;Rust は他の言語と比べると、一度に（コンパイルを挟まずに）長いコードを書きにくいと思います。型推論のある言語ではそうなりがちだと思いますが、 Rust はそれに加えて所有権のエラーがつきものです。うっかりすると修正するうちに実装の目的を忘れてしまう量のエラーが出るので、少しずつコンパイル＆修正を繰り返しながら進めるといいと思います。&lt;/p&gt;

&lt;h3&gt;
  
  
  コンパイル時のエラーメッセージはよく読む
&lt;/h3&gt;

&lt;p&gt;Rust でのコンパイル時のエラーメッセージは長いです。エラーの原因に加えて、その他の情報もたくさん表示されます。しかし、わかりにくいように見えて、 help から始まるメッセージはかなり親切だったりします。&lt;/p&gt;

&lt;p&gt;特に生存期間に関するエラーでは修正例のコードが表示されることがあるので、詰まったらエラーメッセージをよく読むべきです。エラーメッセージや修正例のコードを読んでもその意図がわからなければ、借用を使わずに済む方法を考えた方がいいでしょう。&lt;/p&gt;

&lt;h3&gt;
  
  
  可変なコレクションには mut を指定する
&lt;/h3&gt;

&lt;p&gt;プラクティスというか、単に必須事項なんですけど。コレクションにオブジェクトを追加するなどの破壊的な操作を行うコードがエラー扱いされた場合、変数定義で &lt;code&gt;mut&lt;/code&gt; を付け忘れるケアレスミスが（私は）よくあります。「なんでこれがエラーなんだ？」と思ったら、まず変数定義を確認するといいと思います。&lt;/p&gt;

&lt;h3&gt;
  
  
  エラーハンドリングは Result 型で
&lt;/h3&gt;

&lt;p&gt;ここに、従業員を表す次の構造体があるとします。とりあえずは従業員の名前のフィールドのみ用意するとします。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#[derive(Clone)]
struct Employee {
    name: String
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Employee オブジェクトを生成するとき、 &lt;code&gt;Employee { name: .. }&lt;/code&gt; と直に生成してもいいですが、コンストラクタ関数を実装するとします。シンプルに考えると、関数の型はこうでしょうか。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fn new(name: &amp;amp;str) -&amp;gt; Employee
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;どうせなら入力する名前をチェックしたいですね。空の名前を入力されても困りますから、受け付けられない名前であればエラーとします。&lt;/p&gt;

&lt;p&gt;Result 型を使うタイミングはここです。名前が問題なければ Employee オブジェクトを返し、問題ありならその原因の旨を示すメッセージを返すとします。このエラー処理を捕捉不可能な panic! でやると、プログラムが終了してしまうので注意です。&lt;/p&gt;

&lt;p&gt;Result 型を使うと、コンストラクタ関数はこのように実装できます:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;impl Employee {
    fn new(name: &amp;amp;str) -&amp;gt; Result&amp;lt;Employee, String&amp;gt; {
        if name.is_empty() {
            Err("name must not be empty".to_string())
        } else {
            Ok(Employee { name: name.to_string() })
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;これなら、 Employee オブジェクト生成時のエラーを安全に処理できます。型宣言からもエラーが発生する可能性があるとわかるので、積極的に使いましょう。 try! マクロについても知っておくといいです。（具体例が思いつかなかった）&lt;/p&gt;

&lt;p&gt;最初のうちはエラー値の詳細は置いといて、 Result&amp;lt;T, ()&amp;gt; などと unit 型にしておけばいいと思います。 Option&amp;lt;T&amp;gt; 型で代用したくなることもあるかもしれませんが、 Option 型は目的が異なるので避けましょう。&lt;/p&gt;

&lt;h3&gt;
  
  
  整数や文字列に特別な意味を持たせない
&lt;/h3&gt;

&lt;p&gt;例えば、どの言語にも数値やオブジェクトの比較を行う関数が用意されています。比較の結果は概ね「等しい、小さい、大きい」のいずれかで、これらを表すのに "0, -1, 1" の整数を割り当てる言語があります。もしくは、それらの整数を定数として定義しているかと思います。 Rust ではこのような整数の使い方、整数に特別な意味を持たせる使い方は避けるべきです。&lt;/p&gt;

&lt;p&gt;Rust では列挙体で値の意味を表します。なんだか抽象的な説明ですが、前述の比較の結果は、 Rust ではこう定義されています。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pub enum Ordering {
    Less,
    Equal,
    Greater,
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;列挙体を使うメリットは型検査です。これを整数で表してしまうと、定義外の数値を渡しても型検査が通ってしまいます。&lt;/p&gt;

&lt;p&gt;また、構造体と同様に、列挙体にもメソッドを定義できます。例えば Ordering に定義されている reverse() メソッドは、比較の結果を逆転させます。昇順と降順を切り替えるのに使えます。&lt;/p&gt;

&lt;h3&gt;
  
  
  bool に特別な意味を持たせない（二択でも列挙体を定義する）
&lt;/h3&gt;

&lt;p&gt;前節の続きです。 bool にも特別な意味を持たせないようにすべきです。例えば、扱う値が整数か浮動小数点数のどちらかだとしたら、「 true なら整数、 false なら浮動小数点数」という二択に bool を割り当てるべきではありません。代わりに列挙体でこう定義するといいです。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;enum ValueType {
    Int,
    Float
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  unwrap() の落とし穴
&lt;/h3&gt;

&lt;p&gt;Option 型と Result 型には、一部の列挙体が持つ値（ Some または Ok ）を取得できる unwrap() メソッドがあります。このメソッドは列挙体が None や Err だと panic を発生させますが、その場合はバックトレースの最後尾が unwrap の実装元になります（ lib/std/option.rs とかそんなの）。 unwrap() を呼び出した位置ではないので気を付けたいです。&lt;/p&gt;

&lt;p&gt;バックトレースを有効にしても、 unwrap() を呼び出した行番号まではわからないようです。どうしても unwrap() の呼び出し位置を確認したいなら、 unwrap() 相当の処理をマクロで実装するといいかもしれません。こんな感じでしょうか。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Option.unwrap()
macro_rules! unwrap_opt {
    ($x:expr) =&amp;gt; {
        $x.unwrap_or_else(|| panic!("unwrap failed"))
    }   
}

// Result.unwrap()
macro_rules! unwrap_result {
    ($x:expr) =&amp;gt; {
        $x.unwrap_or_else(|_| panic!("unwrap failed"))
    }   
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  レコードのパターンマッチではフィールド値の変数名を省略する
&lt;/h3&gt;

&lt;p&gt;レコード型（構造体、列挙体）やタプルのパターンマッチでは、フィールド値を代入する変数の記述を省略できます。楽ですので省略しましょう。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;Person&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;me&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Person&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"me"&lt;/span&gt;&lt;span class="nf"&gt;.to_string&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="n"&gt;me&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c"&gt;// { ref name: name } と書かなくてもよい&lt;/span&gt;
        &lt;span class="n"&gt;Person&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;ref&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"name = {}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  クロージャーに関する所有権でつまずいたら move を指定してみる
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://doc.rust-lang.org/book/closures.html"&gt;クロージャー内の所有権の扱いはいくらか複雑です。&lt;/a&gt;所有権に関するコンパイルエラーが出るのに原因も修正方法もわからないときは、クロージャー式の前に move キーワードをつけてみるとコンパイルにパスするかもしれません。&lt;/p&gt;

&lt;p&gt;理屈もわからないのにやってみろというのも適当ですが、先に理屈を理解するには Rust は難しいのではないかと思います。どうしてもクロージャーを使ったコードがコンパイルできないのであれば、不格好でもクロージャーを使わないコードに書き換えてはどうでしょうか。&lt;/p&gt;

&lt;p&gt;また、クロージャーを引数に取る関数を実装しようとすると、関数の型定義がいくらか複雑になります。慣れないうちは、安易にクロージャーを多用しない方がいいのではないでしょうか。&lt;/p&gt;

&lt;h3&gt;
  
  
  再代入可能なグローバル変数を使わない
&lt;/h3&gt;

&lt;p&gt;実行中に再代入可能なグローバル変数（ static mut で定義する可変の静的変数）の内容を書き換えるコード、誰もが（？）つい一度は試してしまうと思います。できることはできるのですが、本当にこの方法でなければできない処理でもなければ、可変のグローバル変数の使用は避けましょう。&lt;/p&gt;

&lt;p&gt;例えば、実行中に書き換える目的で、 Option 型のグローバル変数を定義するとします。次のコードは問題なくコンパイルできます。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;COMMAND&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Option&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;amp;&lt;/span&gt;&lt;span class="nv"&gt;'static&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;Some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"default"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;// static mut の変数へのアクセスは unsafe で囲む&lt;/span&gt;
    &lt;span class="k"&gt;unsafe&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;COMMAND&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;Some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"mycommand"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"command = {}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;COMMAND&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;これがコンパイルをパスするのは、 Option 型の内容が即値（文字列定数）だからです。これを動的に生成される String にするとコンパイルできません。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c"&gt;// None にしても同様&lt;/span&gt;
&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;COMMAND&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Option&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;Some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"default"&lt;/span&gt;&lt;span class="nf"&gt;.to_string&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;エラー:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;anon&amp;gt;:3:38: 3:65 error: mutable statics are not allowed to have destructors [E0397]
&amp;lt;anon&amp;gt;:3 static mut COMMAND: Option&amp;lt;String&amp;gt; = Some("default".to_string());
                                              ^~~~~~~~~~~~~~~~~~~~~~~~~~~
&amp;lt;anon&amp;gt;:3:38: 3:65 help: see the detailed explanation for E0397
&amp;lt;anon&amp;gt;:3:43: 3:64 error: method calls in statics are limited to constant inherent methods [E0378]
&amp;lt;anon&amp;gt;:3 static mut COMMAND: Option&amp;lt;String&amp;gt; = Some("default".to_string());
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;ですので、可変なグローバル変数を有効利用できる状況は非常に限られます。 unsafe の指示が必要な処理はバグの原因にもなりますから、他の方法を検討しましょう。&lt;/p&gt;

&lt;h3&gt;
  
  
  unsafe は諸刃の剣
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://doc.rust-lang.org/book/raw-pointers.html"&gt;生ポインタ&lt;/a&gt;やスレッドセーフなどの&lt;a href="https://doc.rust-lang.org/book/unsafe.html#what-does-safe-mean"&gt;安全ではない処理&lt;/a&gt;は、通常コンパイルエラーになります。どうしてもそういった処理を行いたければ、 &lt;a href="https://doc.rust-lang.org/book/unsafe.html"&gt;unsafe ブロック&lt;/a&gt;内に記述するとコンパイルをパスできます。ただし、より柔軟な処理ができる一方で、当然安全じゃありませんからバグの原因にもなります。「 unsafe を使わざるを得ない」と思ったら、一旦考え直しましょう。&lt;/p&gt;

&lt;h3&gt;
  
  
  実行速度を過信しない
&lt;/h3&gt;

&lt;p&gt;ネイティブコードにコンパイルする言語だからと言って、 Rust で書けば何でも速くなるということはないです。当然、サードパーティーのライブラリが速いとも限りません。わざわざ言われなくてもわかってる、と言われそうですが念のため。&lt;/p&gt;

&lt;p&gt;私が書いてみた範囲では、サイズの大きいオブジェクトを含む Box のコピーで遅くなっていた場合がありました。とは言え必ずしも Box がネックになるとは限りませんし、今後の開発で変わるかもしれません。&lt;/p&gt;

&lt;h2&gt;
  
  
  所有権と生存期間
&lt;/h2&gt;

&lt;h3&gt;
  
  
  不要なクローンをしない
&lt;/h3&gt;

&lt;p&gt;ここで言う不要なクローンとは、 clone() メソッドを呼び出さなくてもコンパイルエラーにならない処理です。&lt;/p&gt;

&lt;p&gt;所有権のエラーに嫌気が差して、とりあえずクローンしとけという考えはお勧めしません。別にクローンのコストを削れなどの実用上の理由ではなくて（もちろんオブジェクトの内容如何でコストが高い場合もあります）、クローンの意味を理解する機会を奪ってしまうからです。エラーが出たら、エラー箇所の周辺に clone() を入れればだいたいは解決できると思うので、そこは一つ我慢して、エラー＆修正の経験値を積むといいと思います。&lt;/p&gt;

&lt;h3&gt;
  
  
  明確な理由を説明できないうちは借用を使わない（例外もある）
&lt;/h3&gt;

&lt;p&gt;Rust と言えば所有権、 Rust と言えば生存期間です。所有権を奪いたくなければ借用を使うことになり、借用を使うなら生存期間を管理する必要があります（生存期間は、コンパイラが推論できる範囲で省略できます）。所有権、借用、生存期間は扱いが複雑なので、ドキュメントやブログなどで詳しく取り上げられたりしてますが、残念ながら学習コストは低くありません。&lt;/p&gt;

&lt;p&gt;ここからは個人的な意見ですが（この記事すべてがそうですが）、 Rust に慣れるまでは、これらの理解を棚上げにしてもいいと思います。特に構造体や列挙体のフィールドに借用を持たせるとなると、生存期間の理解が必要です。借用を使わなければ絶対に実装できないプログラムはそうそうあるものでもないと思います。なぜあなたのコードで借用を使わなければならないのか、その理由を明確に他人に説明できないようでしたら、ひとまず借用の使用は避けておくといいと思います。&lt;/p&gt;

&lt;p&gt;しかし、それでも借用を使うべきであろう場面もありますので、これに続く節も合わせて参考にしてください。&lt;/p&gt;

&lt;p&gt;&lt;a href="http://smallcultfollowing.com/rust-int-variations/imem-umem/guide-strings.html#string-vs.-&amp;amp;str"&gt;少々古いドキュメントですが&lt;/a&gt;、所有権についてこう触れられています。&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you have good reason. It's not polite to hold on to ownership you don't need, and it can make your lifetimes more complex.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;不要に所有権を持つと生存期間の管理が複雑になるからやめとけ、という忠告です。&lt;a href="https://doc.rust-lang.org/book/references-and-borrowing.html#borrowing"&gt;イディオム的でもないよ&lt;/a&gt;ともあります。確かに単純な関数の引数くらいなら、引数で借用すれば所有権を気にする手間が減ると思いますけど、私なんかは Rust に慣れないうちは手間がかかっても所有権の移動のみでなんとかやる方が楽なんじゃないかと思います。&lt;/p&gt;

&lt;p&gt;むしろ、安易に借用を使わない＝不変のオブジェクトを次々と生成しながら処理するコードを書けるスキルの方が、後々重要になるのではないか、とすら思います（ C++ の人たちに怒られるかな？）。借用を使わなければ、所有権絡みのエラーは clone() を闇雲に挟めばなんとかなります。数打ちゃ当たります。打ちまくってるうちに、エラー原因となるコードの勘所もつかめると思います。&lt;/p&gt;

&lt;p&gt;ただ、 Box や標準ライブラリを使う上では借用を気にしなければならない機会も多いのですが、そこは &amp;amp; や * を適当に付けて、気合いで乗り切って頂きたいと思います。&lt;/p&gt;

&lt;h3&gt;
  
  
  所有権を渡す（＝借用の使用を避ける）ことのデメリット
&lt;/h3&gt;

&lt;p&gt;上の節の主旨は「わかんなきゃ借用は使わなくても（所有権を渡しても）いいんじゃない？」なんですが、デメリットもあるんだと押さえておくといいと思います。&lt;/p&gt;

&lt;p&gt;デメリットの一つはコストです。ある値を複数箇所で使うときにいちいち所有権を渡すとなると、その数だけ新しい値を生成するかコピー（クローンもコピー手段の一つ）するかして、新しい所有権を用意する必要があります。当然ながら、生成もコピーもコストがかかります。&lt;/p&gt;

&lt;p&gt;もう一つは、コピーできない値が扱いにくくなることです。他の節で「所有権に関するエラーが出たらクローンしとけばなんとかなる」などと言いましたが、逆に言えば、クローンまたはコピーができなければどうにもならない可能性があります。クローンできない（ Clone トレイトを実装していない）値も多々あります。&lt;/p&gt;

&lt;p&gt;例えば、 File オブジェクトがそうです。ここに、引数に File オブジェクトを所有権ごと受け取る関数があるとします（内容は適当です）。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fn read_all(mut f: File) -&amp;gt; String {
    let mut buf = String::new();
    f.read_to_string(&amp;amp;mut buf);
    buf
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;この関数を呼び出すときは、引数に渡す File オブジェクトの所有権を渡さなければならず、呼び出し後はファイル操作ができなくなります。引数にクローンした値を渡そうにも、 File オブジェクトはクローンできません。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;File&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;io&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="n"&gt;Read&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Seek&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;SeekFrom&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;read_all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;File&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;buf&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;String&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="nf"&gt;.read_to_string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;buf&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;buf&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;File&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"foo.txt"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;read_all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c"&gt;// error: use of moved value: `f`&lt;/span&gt;
    &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="nf"&gt;.seek&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;SeekFrom&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;Start&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;まあこの程度であれば、次のように変更するなどして File の所有権を返せば処理を続けられます。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;read_all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;File&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;File&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;buf&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;String&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="nf"&gt;.read_to_string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;buf&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;buf&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;File&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"foo.txt"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;read_all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="nf"&gt;.seek&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;SeekFrom&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;Start&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;ですが、万事そういうわけにもいかないでしょう。また、あらゆる場面で所有権の授受をしていてはコードが複雑に入り組んでしまいます。 Rust に慣れてきたら、まずは引数から借用を取り入れてみるといいかもしれません。構造体のフィールドに借用を含める場合と違い、だいたいは生存期間を気にする必要はない（省略可能）はずです。&lt;/p&gt;

&lt;p&gt;ちなみに借用を使うと、上のコードはこう書けます。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;File&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;io&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="n"&gt;Read&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Seek&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;SeekFrom&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;read_all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;File&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt;  &lt;span class="nb"&gt;String&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;buf&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;String&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="nf"&gt;.read_to_string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;buf&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;buf&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;File&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"foo.txt"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;read_all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="nf"&gt;.seek&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;SeekFrom&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;Start&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  型
&lt;/h2&gt;

&lt;h3&gt;
  
  
  戻り値を使わない式をエラーにする (unused result which must be used)
&lt;/h3&gt;

&lt;p&gt;セミコロンで区切られた式の値が unit 以外のとき、その値に対して何も操作をしなければ、警告 unused_must_use が表示されます（またはエラー）。例えば次のコードです。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// エラーにする
#![deny(unused_must_use)]

use std::fmt::Write;

fn main() {
    let mut buf = String::new();
    write!(buf, "abc");
    ()
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;





&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;std macros&amp;gt;:2:1: 2:54 error: unused result which must be used
&amp;lt;std macros&amp;gt;:2 $ dst . write_fmt ( format_args ! ( $ ( $ arg ) * ) ) )
               ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
&amp;lt;anon&amp;gt;:7:5: 7:24 note: in this expansion of write! (defined in &amp;lt;std macros&amp;gt;)
&amp;lt;anon&amp;gt;:1:9: 1:24 note: lint level defined here
&amp;lt;anon&amp;gt;:1 #![deny(unused_must_use)]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;このコードのエラー箇所は &lt;code&gt;write!(buf, "abc");&lt;/code&gt; です。セミコロンを終端とする式の値は unit であるべきですが、 &lt;code&gt;write!&lt;/code&gt; マクロの戻り値は &lt;code&gt;Result&amp;lt;(), std::fmt::Error&amp;gt;&lt;/code&gt; です。 Rust では式の値が操作（代入も含む）されないと、 "unused result which must be used" というメッセージで警告されます。値を無視すればバグにつながる可能性があります。&lt;/p&gt;

&lt;p&gt;次の節に続きます。&lt;/p&gt;

&lt;h3&gt;
  
  
  戻り値を無視するには
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;write!&lt;/code&gt; のような連続して使うマクロや関数では、すべての呼び出しで戻り値を処理するのが面倒になることもあります。エラー時に落ちたり見逃したりしてもよければ、戻り値を無視する方法がいくつかあります。&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;_&lt;/code&gt; で始まる変数に値を代入する（ &lt;code&gt;_&lt;/code&gt; を変数名の先頭に付けると、コードブロック内で使わなくても警告されません）&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;#[allow(unused_must_use)]&lt;/code&gt; コンパイラ属性を指定する&lt;/li&gt;
&lt;li&gt;戻り値を無視するマクロを定義する&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;手っ取り早いのは &lt;code&gt;let _ = ..&lt;/code&gt; でアンダースコア付きの変数に代入する方法ですが、私は同等のマクロを定義して使っています。これだと &lt;code&gt;_&lt;/code&gt; への代入よりも無視の意思が明白です。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Write&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;macro_rules!&lt;/span&gt; &lt;span class="n"&gt;ignore&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$x:expr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="mi"&gt;_&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$x&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c"&gt;// unit を返せばよい&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;   
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;buf&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;String&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nd"&gt;ignore!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;writeln!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;buf&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"無視してんのよ"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;もちろん、無視しないに越したことはないです。&lt;/p&gt;

&lt;h3&gt;
  
  
  総称型の型パラメーター名に意味はない
&lt;/h3&gt;

&lt;p&gt;Vec&amp;lt;T&amp;gt; とか Result&amp;lt;T, E&amp;gt; などの T とか E の名前に意味はありません。慣習的に一文字で表しているだけで、 Type や Error などの頭文字を使うことが多いです。&lt;/p&gt;

&lt;p&gt;自分で定義する構造体の型パラメーターの数が多くてわかりにくいようであれば、&lt;a href="https://doc.rust-lang.org/book/associated-types.html"&gt;関連型&lt;/a&gt;の使用を検討するといいかもしれません。関連型は難しそうに見えても、単に書き方を変えただけです。&lt;/p&gt;

&lt;h3&gt;
  
  
  型推論に頼り過ぎない：時には型を宣言する
&lt;/h3&gt;

&lt;p&gt;タプルやコレクションの変数を定義するとき、以降の処理が複雑になりそうであれば、先にコレクションの型を宣言しておくとあとで楽です。&lt;/p&gt;

&lt;p&gt;こんな感じ:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let names: Vec&amp;lt;String&amp;gt; = Vec::new();
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;型推論のエラーは、自分の推測と離れた位置で発生する可能性があります。複雑な型になるとそうなりがちで、間違った型を基準に他の部分も推論が進むと、その結果思い掛けない位置が型エラーとして表示される場合があります。残念ながら、間違いの正確な位置を特定する決定的な方法はありません。&lt;/p&gt;

&lt;p&gt;そこで、あらかじめ変数の型を宣言しておけば、エラー箇所の範囲を狭めやすくなります。それに実装中は型が頭の中に入っていても、席を立って三歩も歩けば忘れます。すべての変数に型を宣言していては面倒過ぎますが、エラー修正に手間取る場合は型を宣言しながらデバッグすると楽になります。特にコレクションの要素の型エラーは追いにくかったので、余程単純な処理でなければ型を宣言しておくといいと思います。&lt;/p&gt;

&lt;h3&gt;
  
  
  Fn, FnMut, FnOnce 型はクロージャーを示す
&lt;/h3&gt;

&lt;p&gt;API リファレンスに登場する Fn* 型は、クロージャーを示す型です。例えば &lt;code&gt;Fn(usize) -&amp;gt; bool&lt;/code&gt; なら、符号なし整数を引数に受け取って真偽値を返すクロージャーを示します。&lt;/p&gt;

&lt;p&gt;Fn, FnMut, FnOnce はどれもクロージャーなんですが、それぞれ性質が異なります。大抵は FnMut が使われるので、当初はそれだけ覚えておけばいいと思います。&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fn: 外側のスコープの変数の内容を変更できません。&lt;/li&gt;
&lt;li&gt;FnMut: 外側のスコープの変数の内容を変更できます。&lt;/li&gt;
&lt;li&gt;FnOnce: このクロージャーは一度しか実行されません。変数の内容は変更できません。&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  所有権に慣れるまではクロージャーを使わない
&lt;/h3&gt;

&lt;p&gt;特にクロージャーから外側のスコープの変数を扱う場合、所有権の管理がかなり面倒になります。所有権に慣れるまでは、クロージャーの使用はごく簡単なケースに留めておくのがいいと思います。&lt;/p&gt;

&lt;h2&gt;
  
  
  構造体と列挙体
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Clone トレイトを自動導出しておく
&lt;/h3&gt;

&lt;p&gt;構造体（列挙体）を定義するときは、同時に &lt;code&gt;#[derive(Clone)]&lt;/code&gt; を記述して Clone トレイトを自動導出（ clone() メソッドを自動的に追加する）しておくといいでしょう。クローンできて困ることはないと思います。フィールドの内容によっては自動導出できない場合もありますが、そのときはがんばって Clone トレイトを実装したりせずに、ひとまず置いて先に進むといいと思います。 Clone トレイトを自動導出できない構造体には、クローンできてしまうとメモリ安全を確保できなくなってしまうフィールドが含まれている可能性が高いと思います。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#[derive(Clone)]
struct Foo {
    ...
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  再帰的な構造体や列挙体を定義したい
&lt;/h3&gt;

&lt;p&gt;自身の型をフィールドに持つ再帰的な構造体や列挙体の定義は、ただ同じ型を指定するだけではできません（ 1.5.0 現在）。例えばこんな感じの構造体です。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;struct Person {
    parent: Option&amp;lt;Person&amp;gt;,
    name: String
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;理屈はともかくとして、これは再帰的に扱う型を Box で囲めば定義できます。 Box を使うので、アクセスの手間は増えます。アクセス時は &lt;code&gt;*&lt;/code&gt; を適当につけて乗り切ってください。コレクション型など　Box を省略できる型もあり、都度調べてください。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;struct Person {
    parent: Option&amp;lt;Box&amp;lt;Person&amp;gt;&amp;gt;,
    name: String
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;ただし、再帰的な構造体、列挙体を定義する前に、本当に必要かどうかを検討すべきだと思います。つい再帰的な構造体を定義したくなりますが、クローン時にやたらとコピーが発生する可能性があって、場合によってはボトルネックになりかねないかもしれません。とは言え最初からパフォーマンスを考えるのも徒労に終わるでしょうから、まずはやってみるといいと思います。列挙体ではわりと必要になると思いますし。&lt;/p&gt;

&lt;p&gt;それなら借用を使ったらどうかと考えると思いますが、型定義と生存期間の管理が途端に複雑になります。このようにすれば一応できなくもないです。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;struct Person&amp;lt;'a&amp;gt; {
    parent: Option&amp;lt;&amp;amp;'a Person&amp;lt;'a&amp;gt;&amp;gt;,
    name: String
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;大抵のケースでは再帰的な借用の管理に悩むだけ時間の無駄だと思いますので、再帰的な構造や借用をできるだけ使わない方法も考えてみるといいと思います。&lt;/p&gt;

&lt;h2&gt;
  
  
  ライブラリ
&lt;/h2&gt;

&lt;h3&gt;
  
  
  sprintf はどこにある？
&lt;/h3&gt;

&lt;p&gt;format! マクロがそれです。&lt;/p&gt;

&lt;h3&gt;
  
  
  文字列バッファはいずこ
&lt;/h3&gt;

&lt;p&gt;String がそれです。 String は可変の文字列です。&lt;/p&gt;

&lt;h3&gt;
  
  
  文字列を結合する
&lt;/h3&gt;

&lt;h4&gt;
  
  
  format!
&lt;/h4&gt;

&lt;p&gt;一つの方法は format! です。文字列にしろ数値にしろ大抵のデータを文字列化できますから、とりあえずはこれで済ませておけば楽でしょう。フォーマットについても "{}" だけ覚えておけばなんとかなります。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let hello = "Hello ";
let world = "world!";
let hello_world = format!("{}{}", hello, world);
print!("{}", hello_world);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h4&gt;
  
  
  String::push_str()
&lt;/h4&gt;

&lt;p&gt;もう一つは String::push_str() メソッドで、既存の文字列に他の文字列を追加できます。このメソッドの引数の型は String ではなく &amp;amp;str なので、 String を結合するなら &amp;amp; をつけます。なぜかって？ 細かいことは後回しです。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let mut hello = "Hello ".to_string();
let world = "world!".to_string();
hello.push_str(&amp;amp;world);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h4&gt;
  
  
  + 演算子
&lt;/h4&gt;

&lt;p&gt;加えて + 演算子があります。 &lt;del&gt;こちらは結合した新しい文字列を返します。&lt;/del&gt; push_str() と同様に引数の型が &amp;amp;str ですので、 String を結合するならやっぱり &amp;amp; が必要です。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let hello = "Hello ".to_string();

// 文字列リテラル &amp;amp;str ならこれで OK
let hello_world = hello + "world!";

// String なら &amp;amp; をつける
let world = "world!".to_string();
let hello_world = hello + &amp;amp;world;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;コメントを頂いて勘違いに気付いたのですが、文字列に対する + 演算子の戻り値は左辺の値です。メモリーアロケーションは発生しません。どういうことかと言うと、 &lt;a href="https://doc.rust-lang.org/src/collections/string.rs.html#1326"&gt;+ 演算子はこう実装されています。&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c"&gt;// Add トレイトで + 演算子を実装できる&lt;/span&gt;
&lt;span class="k"&gt;impl&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;'a&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Add&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;amp;&lt;/span&gt;&lt;span class="nv"&gt;'a&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Output&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="nd"&gt;#[inline]&lt;/span&gt;
    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;other&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="nf"&gt;.push_str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;other&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;self&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;+ 演算子は左辺の値に対して push_str() を呼んでいるだけです。 push_str() との違いは二つ、戻り値があることと、呼び出し時に左辺の値の所有権を譲渡しなければならないことです。とは言え、 push_str() の別名みたいなものですし、そう難しく考えなくてもいいと思います。それに大抵の場合は format! か push_str() を使う方が楽でしょう。&lt;/p&gt;

&lt;h3&gt;
  
  
  コレクションのクローンに注意
&lt;/h3&gt;

&lt;p&gt;もしかすると誰もこんな勘違いはしないかもしれませんが、クローン前とクローン後のコレクションは参照を共有しません。同じ要素を持っていても、それぞれは独立したコレクションです。つまり、 A という Vec をクローンした B があるとして、 B の要素を編集しても A には影響がない、ということです。&lt;/p&gt;

&lt;p&gt;次のコードでは、 vec1 をクローンした vec2 の要素を編集して、それぞれの要素のリストを表示します。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let vec1 = vec![1,2,3,4,5];
let mut vec2 = vec1.clone();
vec2[0] = vec2[0]*2;
vec2[1] = vec2[1]*2;
vec2[2] = vec2[2]*2;
vec2[3] = vec2[3]*2;
vec2[4] = vec2[4]*2;
print!("vec1: ");
for e in vec1.iter() {
    print!("{} ", e)
}
println!("");
print!("vec2: ");
for e in vec2.iter() {
    print!("{} ", e)
}
println!("");
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;実行結果:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;vec1: 1 2 3 4 5 
vec2: 2 4 6 8 10 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;この通り、 vec2 を編集しても vec1 に影響はありません。どうしてだか私は「 vec2 への操作は vec1 に影響する」と思い込んでしまっていて、それを回避しようとして、データ構造を不要に複雑にしてしまったことがあります。かと言って、コレクションを共有しようとして可変の借用を使うと、それはそれで複雑になるので、慣れないと落とし所を見つけるのが難しいかもしれません。基本的には、新しいオブジェクトを作って操作することを考えるべきなのかもしれません。&lt;/p&gt;

&lt;h3&gt;
  
  
  イテレーターを探せ
&lt;/h3&gt;

&lt;p&gt;イテレーター以外の、 map とか　filter とか、コレクションの各要素に対して処理を行う他のメソッドを一度は探すと思います。探してませんか？ 知ってましたか？ さすがです。参りました。&lt;/p&gt;

&lt;p&gt;そこら辺のメソッドはだいたいイテレーターに実装されています。正確には、イテレーターは &lt;a href="https://doc.rust-lang.org/std/iter/trait.Iterator.html"&gt;Iterator トレイト&lt;/a&gt; を実装したオブジェクトですので、この API を探してみてください。難点は、型定義がやたらとややこしそうに見えることでしょうか。とりあえずは、 FnMut という型はクロージャーを指すと覚えておけばなんとかなるかと思います。&lt;/p&gt;

&lt;h3&gt;
  
  
  スマートポインター（または参照カウンター）
&lt;/h3&gt;

&lt;p&gt;Rust で「何を」変更可能とするかはややこしくて、 mut というキーワードだけでも let mut の変数定義と &amp;amp;mut の可変の借用では意味が異なります。変更可能な値を使い回したい場合、単純に考えれば可変の借用を使えばいいのですが、時にはどうしても、借用に頼ることなく、値への参照をオブジェクト間で共有したい or しなければならない場合があります。しかもそういうときに限って、参照先の値を変更可能にしたいことが多いかと思います。できれば設計を見直すべきですが、それでもやっぱり避けられない場合もあるかと思います。一体どんな状況なのよと聞かれても一般的な例が思いつかない。すみません。&lt;/p&gt;

&lt;p&gt;そういうとき、スマートポインター（または参照カウンター）に相当する手段が解決策の一つだったりするかもしれません。で、それはおそらく Rc&amp;lt;RefCell&amp;lt;T&amp;gt;&amp;gt; で実現できます。&lt;a href="http://qiita.com/wada314/items/24249418983312795c08"&gt;詳細はこちらが参考になります。&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;注意しなければならないのは、この種の操作は早い話が「所有権の管理は自分でやれ」ということです。 Rc も RefCell もスレッド間で受け渡しができず、 RefCell は扱い方を誤ると実行時に panic で落ちる可能性があります（その可能性をコンパイラは検出できません）。危険かつ面倒な処理になると思いますが、詳しくは&lt;a href="https://doc.rust-lang.org/book/choosing-your-guarantees.html"&gt;ドキュメント&lt;/a&gt;を参照してください。&lt;/p&gt;

&lt;h2&gt;
  
  
  その他
&lt;/h2&gt;

&lt;h3&gt;
  
  
  スタックオーバーフローの対処
&lt;/h3&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;thread '&amp;lt;main&amp;gt;' has overflowed its stack
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;このエラーが出たら、メインスレッド &amp;lt;main&amp;gt; のスタックが溢れた（オーバーフロー）ということです。このエラーで頻繁にアプリケーションが落ちる場合は、どこかで関数呼び出しをネストし過ぎてないか、無限ループに陥ってないか、まずソースコードを見直します。&lt;/p&gt;

&lt;p&gt;それでも解決しなければ、&lt;a href="http://qiita.com/szktty/items/8a6e26f4b829d3689fce"&gt;スタックサイズを拡大する方法もあります&lt;/a&gt;。当面はバッドノウハウかもしれませんが、この方法でしか乗り切れない場面もあるかもしれません。&lt;/p&gt;

&lt;h3&gt;
  
  
  バックトレースを有効にする
&lt;/h3&gt;

&lt;p&gt;環境変数 RUST_BACKTRACE をセットすると、 panic 発生時にバックトレースが表示されます。現時点では RUST_BACKTRACE の値は何でも構わないようですが、 RUST_BACKTRACE=1 としておくと無難そうです。ただ、各所の行番号は表示してくれないようで、わかりやすいとは言えないかも。&lt;/p&gt;

&lt;p&gt;バックトレースの例:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;thread '&amp;lt;main&amp;gt;' panicked at 'called `Option::unwrap()` on a `None` value', ../src/libcore/option.rs:365
stack backtrace:
   1:        0x109d5e010 - sys::backtrace::tracing::imp::write::he715e18a60aa49cbY7s
   2:        0x109d5d173 - panicking::on_panic::hf85837ce31d02cf7wWw
   3:        0x109d56282 - sys_common::unwind::begin_unwind_inner::h263a8f3a93eff05evas
   4:        0x109d5676e - sys_common::unwind::begin_unwind_fmt::he11604dee4a7c025B9r
   5:        0x109d5c9f7 - rust_begin_unwind
   6:        0x109d7c4b0 - panicking::panic_fmt::hc3363d565c1048da4HJ
   7:        0x109d7befc - panicking::panic::h14af70be4f3d4feaBGJ
   8:        0x109cf0b97 - main::hb74001eb22c0d750Zea
   9:        0x109d5efe2 - sys_common::unwind::try::try_fn::h8880715059644542985
  10:        0x109d5c838 - __rust_try
  11:        0x109d5ee6b - rt::lang_start::hf0f318bf9acb9103hUw
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



</description>
      <category>rust</category>
    </item>
    <item>
      <title>Unity における「カメラ」という考え方</title>
      <dc:creator>SUZUKI Tetsuya</dc:creator>
      <pubDate>Thu, 23 Jan 2020 15:46:09 +0000</pubDate>
      <link>https://dev.to/szktty/unity-h1a</link>
      <guid>https://dev.to/szktty/unity-h1a</guid>
      <description>&lt;p&gt;※この記事は 2014年08月08日 に Qiita に投稿したものです。&lt;/p&gt;




&lt;p&gt;この内容はきっと他の 3D 系開発ツールでも有用だと思いますが、タイトルを「Unity」と限定したのは、私が cocos2d と Unity しか使った経験がないゲーム開発初級者だからです。許せ。&lt;/p&gt;

&lt;h2&gt;
  
  
  カメラの「存在」
&lt;/h2&gt;

&lt;p&gt;通常、私たちはテレビやモニター、あるいは携帯型ゲーム機やらスマホなど専用のディスプレイにゲーム画面を映し出して遊びます。私たちにとっては目に見えている画面=ゲームですが、 3D のゲームでは、開発者が用意した 3D 空間の一部しか画面に映りません（どうにか全部表示しても遊びにくくなるだけですよね）。そのため、プレイヤーがゲーム空間を把握する必要のあるゲームでは、主観視点で歩き回れるようにするなり、マップを回転させるなりしてプレイヤーの手助けをします。こうして、私たちは平面のディスプレイを通して 3D のゲーム空間を覗き込みます。このとき、ディスプレイに映し出される光景を切り出す役を担うのが「カメラ」です。 3D ゲームではカメラはプレイヤーの目となり、また手にもなります。手にもなります。大事なことなので （ry&lt;/p&gt;

&lt;p&gt;まあ言われてみれば「そんなの当然じゃないの？」と思われるかもしれませんが、 3D ゲームの開発にも映像撮影にも縁のなかった私は、普段から 3D のゲームで遊んでいても「自分はカメラを通してゲーム内のオブジェクトを見ている」という考え方をしなかったので、カメラの使い道になかなか気が回りませんでした。 Unity の入門書は何冊か読んだんですけど、読んだ中ではカメラについてのまとまった解説は見当たらなかったんで、覚えたことをまとめておきます。&lt;/p&gt;

&lt;h2&gt;
  
  
  ゲーム空間とディスプレイのギャップを埋めるカメラ
&lt;/h2&gt;

&lt;p&gt;例えば、クリックされたオブジェクトを選択状態にしたいとします。クリックされたディスプレイ上の位置（二次元座標）を取得する API はもちろんあります。ですがその座標でゲーム空間内のオブジェクトを指し示せるのかというと……そうもいきません。オブジェクトがどうディスプレイに映し出されようとも、それはあくまでカメラの視点です。ゲーム空間におけるオブジェクトの位置（三次元座標）とディスプレイ上の位置（二次元座標）はまったくの別物です。「ディスプレイ上の座標 (x, y) に表示されてるオブジェクトを取得したいんだけどさあ」と思っても、オブジェクトたちにすれば「私たちがディスプレイにどう映ってるかなんて知りませんよ。カメラさんに聞いてください」と答えるしかありません。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ゲーム空間（三次元） &amp;lt;-&amp;gt; カメラ &amp;lt;-&amp;gt; ディスプレイ（二次元） &amp;lt;-&amp;gt; プレイヤーの目と手（入力デバイス）
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;具体的な解決方法は後述しますが、このようにゲーム空間とディスプレイの間には座標のギャップがあります。というか間にカメラが入ってるんだから当然と言えば当然ですが、私たちが普段使っている入力デバイス（マウスとかゲーム用のコントローラーとか）も三次元座標を手軽に伝達できるようにはなっていません。ということは、ゲーム空間をディスプレイに表示するのとは逆の方向 -- ディスプレイ上で指定した位置をゲーム空間に関連付ける手段も必要になります。というか間にカメラが入ってるせいでギャップが発生するんだから、これもカメラが解決方法を提供してくれます。&lt;/p&gt;

&lt;p&gt;ちなみにディスプレイ上の座標を「スクリーン座標 (screen point/position) 」、ゲーム空間内の座標を「世界座標、ワールド座標 (world point/position) 」と言います。 “ScreenToXXX” や “WorldToXXX” などの名前の API は、これらの座標を変換します。&lt;/p&gt;

&lt;h2&gt;
  
  
  光線を放つカメラ
&lt;/h2&gt;

&lt;p&gt;カメラの API には、指定した座標に向かって光線を出すメソッドがあります。例えばこうすると、クリックされたゲーム空間内の座標（スクリーン座標じゃないのかって？ とりあえずそういうものだと思ってください）に向かって人には見えない怪光線をカメラから打ち出します。ビビっと。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;Ray&lt;/span&gt; &lt;span class="n"&gt;ray&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Camera&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ScreenPointToRay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mousePosition&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;“Ray” とは「光線」の意です。初めてこのコードを見たときには「何の役に立つんだこんなもの？」と思ったのですが、ちょっと想像してみてください。カメラから出力された光線は、途中で何らかのオブジェクトにぶつかります。そのオブジェクトを「プレイヤーがクリックした（い）オブジェクト」とみなせば、「プレイヤーがクリックしたスクリーン座標から、ゲーム空間内のオブジェクトを指定する」ができるようになるわけです。光線と衝突したオブジェクトを検出するコードは探せば出てきますので、そちらをどうぞ。&lt;/p&gt;

&lt;p&gt;さて今の説明では、最初にゲーム空間内の座標をプレイヤーが指定した前提で進めています。現実には、プレイヤーがクリックできるのはスクリーン座標です。スクリーン座標と世界座標の違いは「 Z 座標（奥行き）の有無」ですね。スクリーン座標は二次元座標ですから Z 座標はありません。ですが、「カメラもオブジェクトの一つである」ことを思い出してください。スクリーン座標がカメラのレンズ上の点であるならば、ここに「カメラからの距離」を加えれば、スクリーン座標を（世界座標を示す）三次元座標に変換できます。上のコードでは「カメラからの距離」を無視してしまっていますが（ゼロ距離とみなしています）、まあ問題が出たら調整すればいいと思います。&lt;/p&gt;

&lt;p&gt;前節で「カメラはプレイヤーの手にもなる」とか「ゲーム空間とディスプレイのギャップを埋める」などと書きました。それらの機能の一つがこれです。&lt;/p&gt;

&lt;h2&gt;
  
  
  立体感の有無
&lt;/h2&gt;

&lt;p&gt;カメラによる「空間の見え方」は一つではありません。デフォルトの設定では、カメラは私たちの目に自然に映るような立体感を持った画像にしてくれます。これを「透視投影モード」と言い、カメラの設定項目に "Perspective" とあるのがそうです。&lt;/p&gt;

&lt;p&gt;これを、もう一つの設定項目である "Orthographic" にすると、立体感を消し去ったような画像にしてくれます（手元に Unity を動かせる環境があるならさっさと試してみるといいでしょう）。立体感のない、つまり距離感のない画像がどんなものかというと、俯瞰図をイメージすると早いです。&lt;/p&gt;

&lt;p&gt;3D 空間を歩き回るゲームなんかだと、俯瞰図って必ず出てくるでしょう？ 簡単なものでは街並みやダンジョンの全体マップだとか、ちょっと形が変わったものだとレーダーも俯瞰図の一種です。立体感を消すだけで多種多様な見せ方ができるのが面白いですね。&lt;/p&gt;

&lt;h2&gt;
  
  
  見せたいものしか映さないカメラ
&lt;/h2&gt;

&lt;p&gt;少し前の立体感の設定の説明で、俯瞰図を例に出しました。全体マップとかレーダーとか、確かに俯瞰図にすれば手軽に実現できそうです。と思って平行投影モードにしてみると、なんだかごちゃごちゃした画面ができてしまいませんでしたか？ 何せすべてのオブジェクトを俯瞰図にしているんですから当然です。求める画面を作るには、余分なオブジェクトを消す……というか、その逆の「見せたいオブジェクトだけを映す」が必要になります。例によって詳細は「レイヤー」とか "Culling Mask" でぐぐってください。&lt;/p&gt;

&lt;p&gt;実際にはカメラとオブジェクトの双方に設定が要りますが、「見せたいオブジェクト」と「立体感の有無」の組み合わせは強力です。特に人以外のレイヤーのオブジェクトが映り込んだ映像には誰もが心惹かれるものですよね。……あ、いわゆる心霊なんとかってやつですよ。&lt;/p&gt;

&lt;h2&gt;
  
  
  カメラは何台でも用意できる
&lt;/h2&gt;

&lt;p&gt;ここまで書いておいて今更ですが、カメラもオブジェクトの一つであり、複数台のカメラをゲーム空間内に配置できます。これも「そんな当然のことわかってるよ」と思われるでしょうけど、多重度の意識は大事ですよね。&lt;/p&gt;

&lt;p&gt;デフォルトではメインカメラ一台のみが用意されています。目まぐるしく視点が切り替わるようなゲームでは、視点ごとにカメラを用意しておいて、必要に応じてカメラを切り替えればよさそうですね。&lt;/p&gt;

&lt;h2&gt;
  
  
  カメラを回転させるために覚えておくこと
&lt;/h2&gt;

&lt;p&gt;Unity （ API じゃなくて開発ツールの方）では、カメラの回転は “Rotation” という項目で、 “x” “y” “z” の三つの値で表されます。これをスクリプトで制御しようとすると、 &lt;a href="http://docs.unity3d.com/ScriptReference/Quaternion.html"&gt;"Quaternion" （クォータニオン）&lt;/a&gt; という値をカメラの “rotation” プロパティにセットすることになります。クォータニオンにも “x” “y” “z” というプロパティがありますが、これに “Rotation” の項目と同じ値をセットしても思うようには動きません。&lt;/p&gt;

&lt;p&gt;スクリプトによるカメラ操作のとっかかりとしては、次の点を押さえておけばいいと思います。まあ私も全然詳しくないです。&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;オブジェクトの回転（姿勢）はクォータニオンという概念で表される。&lt;/li&gt;
&lt;li&gt;開発ツールで設定できる “Rotation" の値とクォータニオンの値は同一ではない。&lt;/li&gt;
&lt;li&gt;“Rotation” の値をクォータニオンに変換するには、 &lt;code&gt;Quaternion.Euler&lt;/code&gt; 関数を使えばよい。&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>unity3d</category>
    </item>
    <item>
      <title>リソースオブジェクトについて</title>
      <dc:creator>SUZUKI Tetsuya</dc:creator>
      <pubDate>Thu, 23 Jan 2020 15:43:54 +0000</pubDate>
      <link>https://dev.to/szktty/-6g5</link>
      <guid>https://dev.to/szktty/-6g5</guid>
      <description>&lt;p&gt;※この記事は 2014年12月17日 に Qiita に投稿したものです。 crypto に関する記述は Erlang 17.3 時点で、現在の最新版では仕様が変わっています。&lt;/p&gt;




&lt;h2&gt;
  
  
  リソースオブジェクトとは
&lt;/h2&gt;

&lt;p&gt;NIF で使われるデータ型の一つにリソースオブジェクトがあります。リソースオブジェクトとは任意のデータをラップして Erlang との橋渡しをするデータで、主に構造体へのポインタをラップするのに使われます。 Erlang レベルにリソースオブジェクトを渡す場合は、リソースオブジェクトを持つリソース項を生成して渡します。 Erlang レベルからリソースオブジェクトを受け取るには、受け取ったリソース項からリソースオブジェクトを取り出します。ややこしいですね。&lt;/p&gt;

&lt;p&gt;リソース項はなぜか Erlang レベルではバイナリ型とみなされますが (&lt;code&gt;is_binary/1&lt;/code&gt; が真になる) 、内容は隠蔽されて見えなくなります。また、ラップするデータごとにリソース型 (resource type) を用意しておくことで、引数として受け取ったリソースオブジェクトを区別でき、不正な型のデータが NIF に渡ってしまうのを防げます。&lt;/p&gt;

&lt;h2&gt;
  
  
  リソースオブジェクトを使わない場合
&lt;/h2&gt;

&lt;p&gt;NIF レベルで使うデータを Erlang レベルに渡したい場合、数値や文字列のような単純なデータなら、ストレートに Erlang 項に変換すれば簡単です。値の妥当性検査も簡単です。&lt;/p&gt;

&lt;p&gt;問題はバイナリや構造体のような検査しにくいデータを Erlang レベルに渡す場合で、データをバイナリ項で表したり、ポインタ値を整数項にするなどで Erlang レベルに露出させてしまうと VM が落ちる原因になる可能性があります。&lt;/p&gt;

&lt;p&gt;Erlang の項はすべて不変ですので項の内容は変更できませんし、直ちに問題が起こるわけではありません。問題は、項を NIF レベルで処理するときに起こります。&lt;/p&gt;

&lt;p&gt;例えば crypto モジュールがこの問題を抱えています (抱えているっつーかほったらかしっつーか) 。対話型シェルで次のコードを入力すると VM が落ちるはずです。 (17.3 で確認)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ erl
Erlang/OTP 17 [erts-6.2] [source] [64-bit] [smp:12:12] [async-threads:10] [kernel-poll:false]

Eshell V6.2  (abort with ^G)
1&amp;gt; {sha256, C1} = crypto:hash_init(sha256). 
{sha256,&amp;lt;&amp;lt;103,230,9,106,133,174,103,187,114,243,110,60,
          58,245,79,165,127,82,14,81,140,104,5,155,171,
          217,131,...&amp;gt;&amp;gt;}
2&amp;gt; C2 = list_to_binary(lists:reverse(binary_to_list(C1))).
&amp;lt;&amp;lt;0,0,0,32,0,0,0,0,0,0,0,0,0,0,19,204,0,0,0,1,17,116,12,
  216,0,0,0,1,0,...&amp;gt;&amp;gt;
3&amp;gt; crypto:hash_update({sha256, C2}, &amp;lt;&amp;lt;123&amp;gt;&amp;gt;).
Segmentation fault: 11
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;これでなぜ落ちるのかというと、 &lt;code&gt;hash_update/2&lt;/code&gt; が受け取ったバイナリが、 OpenSSL 内部で使われる構造体のデータとしてストレートに OpenSSL の関数に渡ってしまうからです。これを防ぐには引数の内容をチェックするか、そんなことはめんどくさいし完璧にはできないので、リソースオブジェクトを使うと安全です。&lt;/p&gt;

&lt;p&gt;前述の crypto モジュールでは、 HMAC の関数でのみリソースオブジェクトが使われています。 &lt;code&gt;hmac_init/2&lt;/code&gt; を実行すると、表面上は空のバイナリに見えるデータが返ってきます。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;11&amp;gt; C = crypto:hmac_init(sha256, &amp;lt;&amp;lt;&amp;gt;&amp;gt;).                   
&amp;lt;&amp;lt;&amp;gt;&amp;gt;
12&amp;gt; is_binary(C).
true
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  リソースオブジェクトの操作
&lt;/h2&gt;

&lt;h3&gt;
  
  
  メモリ管理
&lt;/h3&gt;

&lt;p&gt;リソースオブジェクトのメモリ管理は参照カウントで行われます。 Erlang 項ではないため GC には回収されません。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;     Erlang レベル                           NIF レベル
&amp;lt;----------------------&amp;gt;       &amp;lt;----------------------------------&amp;gt;
リソース項 (ERL_NIF_TERM) &amp;lt;----&amp;gt; リソースオブジェクト &amp;lt;----&amp;gt; 任意のデータ
    GC に回収される                 参照カウント
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;リソースオブジェクトから生成したリソース項、これは Erlang のオブジェクトなので GC に回収されます。&lt;/li&gt;
&lt;li&gt;リソース項が解放されると、リソース項が保持していたリソースオブジェクトへのオーナーシップが取り消されます。要は参照カウントが一つ減ります。&lt;/li&gt;
&lt;li&gt;リソースオブジェクトは参照カウントが 0 になると解放されます。&lt;/li&gt;
&lt;li&gt;リソースオブジェクトが解放されるとデストラクタ関数 (&lt;code&gt;enif_open_resource_type()&lt;/code&gt; で指定します) が呼ばれ、ラップされていたデータの解放処理が行われます。&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;参照カウントの増減するタイミングはこうです:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;リソースオブジェクトを生成すると (&lt;code&gt;enif_alloc_resource&lt;/code&gt;) 、カウントは 1 になる&lt;/li&gt;
&lt;li&gt;リソース項を生成すると (&lt;code&gt;enif_make_resource&lt;/code&gt;) 、カウントが 1 増える&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;enif_keep_resource&lt;/code&gt; を呼ぶと、カウントが 1 増える&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;enif_release_resource&lt;/code&gt; を呼ぶと、カウントが 1 減る&lt;/li&gt;
&lt;li&gt;リソース項が GC に回収されると、カウントが 1 減る&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;増減のタイミングはいくつもありますが、基本的には「 alloc/keep したらどこかで release する」です。もちろん、解放したくなければ release する必要はありません。&lt;/p&gt;

&lt;h3&gt;
  
  
  リソース型を生成する
&lt;/h3&gt;

&lt;p&gt;リソースオブジェクトの準備として、まずはリソースオブジェクトの内容を区別するためのリソース型を &lt;code&gt;enif_open_resource_type&lt;/code&gt; で生成しておきます。 rebar で NIF のテンプレートを指定してプロジェクトファイルを作ると、リソース型を生成するコードも含まれます。&lt;/p&gt;

&lt;p&gt;こんな感じ。 &lt;code&gt;enif_open_resource_type&lt;/code&gt; は特定のコールバック (load, reload, upgrade) でのみ呼べます。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;static ErlNifResourceType *rt;

static int
on_load(ErlNifEnv* env, void** priv_data, ERL_NIF_TERM load_info)
{
  ErlNifResourceFlags flags = ERL_NIF_RT_CREATE | ERL_NIF_RT_TAKEOVER;
  rt = enif_open_resource_type(env, NULL,
      "resource_name",   /* リソース名 */
      &amp;amp;resource_cleanup, /* リソースの解放処理を行う関数 */
      flags, NULL);
  if (rt == NULL)
    return -1;

  return 0;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  リソースオブジェクトを生成する
&lt;/h3&gt;

&lt;p&gt;リソースオブジェクトの生成から破棄までが一つの関数内で完結するような単純な処理であれば、だいたい次の流れで書けます。&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;リソースオブジェクトを生成する (&lt;code&gt;enif_alloc_resource&lt;/code&gt;) -&amp;gt; 参照カウントは 1&lt;/li&gt;
&lt;li&gt;リソース項を生成する (&lt;code&gt;enif_make_resource&lt;/code&gt;) -&amp;gt; 参照カウントは増えて 2&lt;/li&gt;
&lt;li&gt;リソースオブジェクトの参照を減らす (&lt;code&gt;enif_release_resource&lt;/code&gt;) -&amp;gt; 参照カウントは 1 。リソース項が GC に回収されると 0 になる&lt;/li&gt;
&lt;li&gt;リソース項を返す&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;次のコードは&lt;a href="http://www.erlang.org/doc/man/erl_nif.html"&gt;ドキュメントに掲載されているサンプル&lt;/a&gt;です。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    ERL_NIF_TERM term;

    /* リソースオブジェクトを生成する */
    MyStruct* obj = enif_alloc_resource(my_resource_type, sizeof(MyStruct));

    /* 構造体を初期化する ... */

    /* リソース項を生成する */
    term = enif_make_resource(env, obj);

    if (keep_a_reference_of_our_own) {
        /* 'obj' を静的変数に代入するなら release の必要はない */
    }
    else {
        /* リソースオブジェクトの参照カウントを減らす */
        enif_release_resource(obj);
    }
    return term;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;これまでリソースオブジェクトがリソースオブジェクトがーと連呼してきましたが、リソースオブジェクトそのものを示す型は NIF では登場しません。 &lt;code&gt;enif_alloc_resource&lt;/code&gt; が返すのは、指定したサイズのメモリブロックへのポインタ (&lt;code&gt;void *&lt;/code&gt;) です。実行中の参照カウントの値を知る方法もありませんので、参照カウントではまるとデバッグが面倒です。&lt;/p&gt;

&lt;h3&gt;
  
  
  リソース項からデータを取得する
&lt;/h3&gt;

&lt;p&gt;リソース型を指定し、 &lt;code&gt;enif_get_resource&lt;/code&gt; で取得します。指定のリソース型以外の型はすべて弾かれます。 Erlang レベルではリソース項を改竄できませんから、これで引数にどんな値が来ても大丈夫です。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;static ERL_NIF_TERM my_func(ErlNifEnv* env, int argc, const ERL_NIF_TERM a
rgv[])
{
  my_resource *data;
  if (!enif_get_resource(env, argv[0], my_resource_type, (void **)&amp;amp;data))
    return 0;
    ...
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  まとめ
&lt;/h2&gt;

&lt;p&gt;君も crypto モジュールを修正すれば Erlang/OTP に contribute できるチャンス！...だと思いますがどなたかどうですか。私はめんどくさいのでいいです。&lt;/p&gt;

</description>
      <category>erlang</category>
    </item>
    <item>
      <title>OCaml で return 相当の処理を実装する</title>
      <dc:creator>SUZUKI Tetsuya</dc:creator>
      <pubDate>Thu, 23 Jan 2020 15:36:03 +0000</pubDate>
      <link>https://dev.to/szktty/ocaml-return-2pmc</link>
      <guid>https://dev.to/szktty/ocaml-return-2pmc</guid>
      <description>&lt;p&gt;※この記事は 2016年02月15日 に Qiita に投稿したものです。&lt;/p&gt;




&lt;p&gt;OCaml には return 文（または式）がありません。 OCaml の関数は最後に評価された式の値を戻り値とします。ですので、戻り値に関しては return が不要なのですが、関数の実行の中断（脱出）もできません。&lt;/p&gt;

&lt;p&gt;ですが、 Jane Street Core に含まれる &lt;a href="https://github.com/janestreet/core_kernel/blob/master/src/with_return.ml#L5"&gt;with_return 関数&lt;/a&gt;が同等の処理を実装しています。このソースをいきなり読むのは初級者には難しかったんで、実現したい仕様からコードを逆算して考えていきます。なお、以降のコードは Core に依存しません。&lt;/p&gt;

&lt;p&gt;まずは、関数の使い方です。次のような使い方を想定しています。ソースは &lt;a href="https://github.com/janestreet/core_kernel/blob/master/src/common.mli#L97"&gt;common.mli&lt;/a&gt; のコメントから、 Core に依存しない形に修正しています:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight ocaml"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;find&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="n"&gt;l&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="n"&gt;with_return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
    &lt;span class="nn"&gt;List&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;iter&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Some&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nc"&gt;None&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;これは List.find の実装例です。実際の &lt;a href="https://github.com/janestreet/core_kernel/blob/master/src/core_list0.ml#L338"&gt;Core.Std.List.find&lt;/a&gt; は with_return を使っていませんので、あくまで一例です。 return を含める処理をクロージャーで書いて、それを with_return に渡します。 List.find は再帰で簡単に書けますが、 return のある言語に慣れている人にとってはこちらのコードの方がわかりやすいかもしれません。&lt;/p&gt;

&lt;p&gt;では、 with_return の実装方法を考えていきます。その前に、使い方を示しておいてなんですが、上の例では &lt;code&gt;r.return&lt;/code&gt; のように、 return 関数はレコード r のメンバーです。でも r は必要なのか？ return 関数のみを渡せばいいんじゃないのか？と私は思ったので、その使い方を想定してみます:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight ocaml"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;find&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="n"&gt;l&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="n"&gt;with_return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="n"&gt;return&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
    &lt;span class="nn"&gt;List&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;iter&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt; &lt;span class="n"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Some&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nc"&gt;None&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;多少シンプルになりました。これで考えてみます。&lt;/p&gt;

&lt;p&gt;with_return は引数に関数を一つ受け取りますから、こんな感じで始まりますね。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight ocaml"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;with_return&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;..&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;次に、 f に渡す return 関数を考えます。 with_return なんてクッションを置かずに一つの関数で return を済ませられればいいのですが、さすがに無理です。仕方がないので f 内で return を使ってもらいます。 return は関数内で実装するとして、こんな感じです:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let with_return f =
  let return value = .. in
  f return (* あとはなんとかして戻り値を処理したい *)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;今度は、 return を呼んだら関数 f を脱出する処理です。そんな処理を書けるのか？と言えば、そこは例外を利用すればいけます。例外を上げれば f を脱出できますから、その例外を捕捉すればいけそうです。例外は専用の型を別途用意するとします:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight ocaml"&gt;&lt;code&gt;&lt;span class="k"&gt;exception&lt;/span&gt; &lt;span class="nc"&gt;Return&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="k"&gt;'&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;

&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;with_return&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;return&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Return&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;in&lt;/span&gt;
  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="n"&gt;return&lt;/span&gt; &lt;span class="k"&gt;with&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nc"&gt;Return&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;..&lt;/span&gt; &lt;span class="c"&gt;(* 戻り値の処理 *)&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;exn&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="n"&gt;exn&lt;/span&gt; &lt;span class="c"&gt;(* 他の例外だったらスルーしとこう *)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;List.find の例くらいなら問題なくいけそうな気が...コンパイルできない。どうやら &lt;code&gt;exception Return of 'a&lt;/code&gt; はコンパイルできないようです。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# exception Return of 'a;;
Error: Unbound type parameter 'a
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;型変数 'a が宣言されていないとのエラーですが、例外に型変数は指定できません。 OCaml の例外の型は exn で、ユーザー定義の例外は exn の型コンストラクタとして扱われます。偉そうに言ってますが、私はナチュラルに間違えました。&lt;/p&gt;

&lt;p&gt;exn は型変数を持たないので、 &lt;code&gt;exception Return of 'a&lt;/code&gt; の 'a は無効です。定義するなら、 &lt;code&gt;exception Return of string&lt;/code&gt; のように具体的な型を指定する必要があります。関数の性質上、特定の型に絞ると使いにくいので、この方法ではだめそうです。&lt;/p&gt;

&lt;p&gt;これを解決するにはどうするか。例外のデータ型に型変数を指定できないなら、どうにかして戻り値の型ごとの例外を定義してはどうでしょう。でも、&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;exception Return_string of string
exception Return_bool of bool
exception Return_int of int
..

let with_return_string f = ..
let with_return_bool f = ..
let with_return_int f = ..
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;などと、型ごとに例外と関数を定義するのは面倒ですし、 with_return を内部で使う関数の型を抽象化しにくくなります。ここでの例で言えば、&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight ocaml"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;find&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="n"&gt;l&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="n"&gt;with_return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="n"&gt;return&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
    &lt;span class="nn"&gt;List&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;iter&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt; &lt;span class="n"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Some&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nc"&gt;None&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;code&gt;'a list -&amp;gt; ('a -&amp;gt; bool) -&amp;gt; 'a option&lt;/code&gt; としたい find 関数の型が、次のように型別の with_return を使うことによって、&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight ocaml"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;find&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="n"&gt;l&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="c"&gt;(* 戻り値は文字列 *)&lt;/span&gt;
  &lt;span class="n"&gt;with_return_string&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="n"&gt;return&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
    &lt;span class="nn"&gt;List&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;iter&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt; &lt;span class="n"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Some&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nc"&gt;None&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;code&gt;string list -&amp;gt; (string -&amp;gt; bool) -&amp;gt; string option&lt;/code&gt; のように限定されてしまいます。仕方がないから find も型ごとに find_string, find_bool...と用意するとなると、さすがにこれでは使いにくい。&lt;/p&gt;

&lt;p&gt;できるならば、 with_return の呼び出し箇所に応じて、戻り値の型に合わせた例外を自動的に定義したい。そんなことが可能なのかと言えば、できるらしいです。&lt;a href="http://caml.inria.fr/pub/docs/manual-ocaml/extn.html#sec228"&gt;局所的抽象型 (locally abstract types)&lt;/a&gt; という仕様で、関数内でのみ有効な抽象型を扱えます。ただし関数内では例外を定義できませんので、モジュール定義と組み合わせます。つまり、（戻り値の型を含む）例外を含むモジュールを関数内で定義する、ということです。わからない？ごもっともです。要するに次の形で書けます:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight ocaml"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;with_return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 
  &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nc"&gt;M&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt;
    &lt;span class="k"&gt;exception&lt;/span&gt; &lt;span class="nc"&gt;Return&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt;
  &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;return&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;M&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Return&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;in&lt;/span&gt;
  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="n"&gt;return&lt;/span&gt; &lt;span class="k"&gt;with&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nn"&gt;M&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Return&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;exn&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="n"&gt;exn&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;code&gt;(type value)&lt;/code&gt; という謎の記述が局所的抽象型です（ OCaml 3.12 からの機能で、全然最新ではないんですが）。これは引数ではなくて、関数内でのみ有効な抽象型 value の宣言です。 value という特定の型があるわけではないです。&lt;/p&gt;

&lt;p&gt;前述のように、関数内では例外を直接定義できません。そのためモジュール定義と組み合わせたのが&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight ocaml"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nc"&gt;M&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt;
  &lt;span class="k"&gt;exception&lt;/span&gt; &lt;span class="nc"&gt;Return&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;のコードです。この struct は何なのか？モジュール定義で書くアレじゃないのか？そうです、モジュールの定義（というか生成）です。ここで戻り値用の例外 Return を含む新しいモジュール M を生成してます。実はモジュールはファーストクラスオブジェクトで、値として操作可能、動的に生成できます（詳しくは RWO の &lt;a href="https://realworldocaml.org/v1/en/html/first-class-modules.html"&gt;First Class Modules&lt;/a&gt; を参照してください）。静的型付けの OCaml で動的にモジュールを生成ってなに？と混乱しそうだったら、モジュールというものを深く考え過ぎているのかもしれません。静的に型付けすることと、動的に（実行時に）モジュールオブジェクトを生成するのは、それぞれ別の処理です。&lt;/p&gt;

&lt;p&gt;ややこしい説明は続きます。そのモジュール定義に含まれた例外で抽象型 value を指定していますが、先を見た方がわかりやすいでしょう。例外 Return を使っている箇所はここです（引数の value と type value は名前が同じですが、前者は値、後者は型で、名前空間が異なる別のデータです。同じ名前を使う必要はありません）:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let return value =
  raise (M.Return value)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;引数（ユーザーが戻り値とする値）を例外 Return でラップして、例外を上げます。従って引数 value の型は、局所的抽象型の value です。これでどうなるのかと言うと、「実行時に戻り値の型用の例外を含むモジュールが生成され、型推論時に例外の型が決定される」とすればいいんでしょうが、説明されるよりコードを理解する方が早いかもしれませんね。&lt;/p&gt;

&lt;p&gt;これで一応の機能はできました。これ以降ですが、 Core の実装では with_return から渡される関数 return の呼び出しを with_return の実行内に制限しています。 Core に依存しない形にしてみると、こんな感じです:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let with_return (type value) f = 
  let module M = struct
    exception Return of value
  end in
  let is_alive = ref true in
  let return value =
    if not !is_alive then
      failwith "already returned";
    raise (M.Return value)
  in  
  try 
    let value = f return in
    is_alive := false;
    value
  with exn -&amp;gt;
    is_alive := false;
    match exn with
    | M.Return value -&amp;gt; value
    | _ -&amp;gt; raise exn
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;with_return に渡す関数の呼び出し後に return 関数を呼び出すとエラー（例外だけど）にします。そうする理由は with_return の実装の隠蔽でしょうか。万が一 return が with_return 外に持ち越されてしまった場合に思わぬ箇所で例外が上がってしまうとか、あるいは例外 Return がローカルなモジュールに定義されているので、ユーザーからは例外 Return を捕捉する方法がないとか。特にコメントが書かれていませんので、私の OCaml レベルではわかりません。ただ、 Core でも failwith 使っとくんだなとはわかりました。&lt;/p&gt;

&lt;p&gt;さて、最後は型です。これまでの実装だと、 with_return の型はこうです。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;val with_return : (('a -&amp;gt; 'b) -&amp;gt; 'a) -&amp;gt; 'a
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;('a -&amp;gt; 'b) が return 関数の型です。ここなんですが、もちろん return 関数が取る引数 'a は戻り値として渡す型です。では、 return 関数の戻り値 'b は何でしょう？ややこしいようですが、例えば &lt;code&gt;return true&lt;/code&gt; という式があったら、その戻り値は何でしょうか。 bool ではないです。というのは、 return 関数は必ず例外を上げるからです:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let return value =
  if not !is_alive then
    failwith "already returned";
  raise (M.Return value)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;return 関数で最後に評価されるのは、例外を上げる raise 関数です。 raise の型は exn -&amp;gt; 'a で、 return 関数の戻り値もここに関係します。で、この戻り値 'a は何なのか？&lt;/p&gt;

&lt;p&gt;例外を上げてしまいますから、 raise から戻り値は返ってきません。それなら unit にしてもよさそうに見えますが、 'a であるのは対になる式と型を合わせるためかと思います。例を出しますと、 val bool_of_string : string -&amp;gt; bool はこう実装できます:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight ocaml"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;bool_of_string&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="s2"&gt;"true"&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="bp"&gt;true&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="s2"&gt;"false"&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="bp"&gt;false&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Invalid_argument&lt;/span&gt; &lt;span class="s2"&gt;"bool_of_string"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;上二つのパターンマッチ後の値が bool であるのに、最後のパターンマッチが raise で終わっても問題ないのは、 raise の型が exn -&amp;gt; 'a だからです。この場合ですと、'a は bool に置き換えられます。もし raise の戻り値が unit であれば、実際には使われない適当な値を書く必要が出てきます。 'a のおかげで余計なコードを書かなくて済むというわけです。&lt;/p&gt;

&lt;p&gt;というわけで話を return 関数に戻しますと、 ('a -&amp;gt; 'b) の 'b は raise の戻り値です。深く考える必要はない..かもしれませんが、こういう手続き的なコードを書くとしたらどうなるでしょうか？&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight ocaml"&gt;&lt;code&gt;&lt;span class="c"&gt;(* 実用的な意味はありません *)&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;map&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="n"&gt;l&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="n"&gt;with_return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="n"&gt;return&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nn"&gt;List&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt; &lt;span class="n"&gt;l&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;
      &lt;span class="n"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;(* ポイント *)&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;map&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;List&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
      &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="k"&gt;with&lt;/span&gt;
      &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nc"&gt;None&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;None&lt;/span&gt;
      &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nc"&gt;Some&lt;/span&gt; &lt;span class="n"&gt;x'&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;x'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;l&lt;/span&gt;
    &lt;span class="k"&gt;in&lt;/span&gt;
    &lt;span class="nc"&gt;Some&lt;/span&gt; &lt;span class="n"&gt;map&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;この関数の私が意図した型は&lt;/p&gt;

&lt;p&gt;('a -&amp;gt; 'b option) -&amp;gt; 'a list -&amp;gt; 'b list option&lt;/p&gt;

&lt;p&gt;です。ところが、このコードを型注釈なしにコンパイルすると、&lt;/p&gt;

&lt;p&gt;('a -&amp;gt; unit option) -&amp;gt; 'a list -&amp;gt; unit list option&lt;/p&gt;

&lt;p&gt;こう推論されます。なぜ unit になるかと言えば、最初の return 呼び出しの戻り値が unit だからです。従って次の return も unit 、従って x' も unit であり、従って f は ('a -&amp;gt; unit option) と推論されます。これでは困るので、次のように型注釈をつけてコンパイルしてみます。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight ocaml"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;map&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="n"&gt;l&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;'&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;'&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="n"&gt;option&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;'&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="kt"&gt;list&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;'&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="kt"&gt;list&lt;/span&gt; &lt;span class="n"&gt;option&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;..&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;するとコンパイルエラーが出ました。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Error: This expression has type unit list option
       but an expression was expected of type
         ('a -&amp;gt; 'b option) -&amp;gt; 'a list -&amp;gt; 'b list option
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;まあ、そりゃそうですね。最初の return 呼び出しの戻り値が unit であることに変わりませんから。と、このように複数箇所で return を使う場合は、戻り値を揃えないといけません。&lt;/p&gt;

&lt;p&gt;しかし、これは少々トリッキーな方法で解決できるようです。とは言え Obj.magic のようなチートではなく、高ランク多相とかランクN多相とか言われる型表現を、多相レコードで表します。 Core のコメントには、こう書きたいんだけど ML の表現力では無理だから多相レコードを使ったとあります。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight ocaml"&gt;&lt;code&gt;&lt;span class="c"&gt;(* エラーですよ *)&lt;/span&gt;
&lt;span class="k"&gt;val&lt;/span&gt; &lt;span class="n"&gt;with_return&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;'&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="k"&gt;'&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;'&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="k"&gt;'&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;'&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;'&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;'a. と 'b. のピリオド付き型変数は、型変数の宣言です（この文法は存在しますが、このようには書けません）。何の意味が？というと、型変数のスコープを指定できます。というかしたいんだけど OCaml ではできないので、あくまで疑似コードです。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;val with_return : 'a. (('a -&amp;gt; ('b. 'b)) -&amp;gt; 'a) -&amp;gt; 'a
                   |            +---+              |
                   |             'b                |
                   +-------------------------------+
                                 'a
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;これがどう return に影響すると言うのか？ return の型は ('a -&amp;gt; 'b) でした。 OCaml では（他の言語について詳しくないのでこういう書き方をしてます）、型変数は関数の実装全体で有効です。ですので、一旦 'a と 'b が決定してしまえば、残りの return 呼び出しも同じ型とみなされます。しかし上の宣言が有効だとすれば、 'b の有効範囲は return の戻り値に限定されます。 'b は関数の型には影響せず、 return の呼び出し箇所ごとに決定されるわけです。従って前述の例のように、 return の戻り値が unit である箇所とそうでない箇所があっても、それぞれで 'b が決定されるので問題ないということになります。おそらくこれを高ランク多相とかランクN多相と言うのだと思いますが、 OCaml ユーザーには&lt;a href="https://gihyo.jp/dp/ebook/2012/978-4-7741-5314-8"&gt;プログラミング in OCaml&lt;/a&gt; の「 12.5.4 多相メソッド」の項が参考になるかと思います。&lt;/p&gt;

&lt;p&gt;さて、繰り返したように上記の仕様は OCaml で実装できないのですが、多相フィールドを持つレコードを使うとなんとかなります。それが次の定義です。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type 'a return = { return : 'b. 'a -&amp;gt; 'b }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;'b. 以外のコードは特に問題ないでしょう。問題は &lt;code&gt;return : 'b. 'a -&amp;gt; 'b&lt;/code&gt; の部分です。 'b. が型変数のスコープだと言われても、それがどうこの定義に関係するのか？&lt;/p&gt;

&lt;p&gt;これまでに登場した return の型は 'a -&amp;gt; 'b でした。ここでもそれは変わりません。ところが、 'b は左辺に登場しません。 'b は return 関数呼び出しの文脈でのみ具体化され、レコードに影響しません。多相メソッドとも言い、繰り返しますが、詳しくは&lt;a href="https://gihyo.jp/dp/ebook/2012/978-4-7741-5314-8"&gt;プログラミング in OCaml&lt;/a&gt; の「 12.5.4 多相メソッド」の項が参考になるかと思います。&lt;/p&gt;

&lt;p&gt;ともかく、この多相フィールドを使うことで、 'a. (('a -&amp;gt; ('b. 'b)) -&amp;gt; 'a) -&amp;gt; 'a のような型変数のスコープを用意できます。というわけで、 'a return 型は return 関数を持つレコードで、 'a は return 関数に渡す戻り値の型です。そして、最終的に with_return 関数の型はこうなります。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;val with_return : ('a return -&amp;gt; 'a) -&amp;gt; 'a
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;以上です。まさか with_return 関数一つに、局所的抽象型、ファーストクラスモジュール、多相フィールドと、濃い仕様がいくつも詰まってるとは思いませんでした。 Core を使う分にはここまで把握しなきゃならないことはないと思いますので、臆せず OCaml と Core にチャレンジしていただければと思います（なかなかそんな人いないか..）。&lt;/p&gt;

&lt;p&gt;最後に、実際のコードを引用しておきます。途中で参照されている Exn モジュールは Core の API ですので、そこだけ raise に置き換えれば Core 非依存にできます。 OCaml レベルを上げたければ、この関数に頼らない方がいいんじゃないかなと思います。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight ocaml"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="k"&gt;'&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;return&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;return&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;'&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="k"&gt;'&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;'&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;with_return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nc"&gt;M&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt;
    &lt;span class="c"&gt;(* Raised to indicate ~return was called.  Local so that the exception is tied to a
       particular call of [with_return]. *)&lt;/span&gt;
    &lt;span class="k"&gt;exception&lt;/span&gt; &lt;span class="nc"&gt;Return&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt;
  &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;is_alive&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ref&lt;/span&gt; &lt;span class="bp"&gt;true&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt;
  &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;return&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;not&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;is_alive&lt;/span&gt;
    &lt;span class="k"&gt;then&lt;/span&gt; &lt;span class="n"&gt;failwith&lt;/span&gt; &lt;span class="s2"&gt;"use of [return] from a [with_return] that already returned"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nn"&gt;Exn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;raise_without_backtrace&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;M&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Return&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;in&lt;/span&gt;
  &lt;span class="k"&gt;try&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;return&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt;
    &lt;span class="n"&gt;is_alive&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="bp"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;a&lt;/span&gt;
  &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;exn&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
    &lt;span class="n"&gt;is_alive&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="bp"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="n"&gt;exn&lt;/span&gt; &lt;span class="k"&gt;with&lt;/span&gt;
    &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nn"&gt;M&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Return&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;
    &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="n"&gt;exn&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



</description>
      <category>ocaml</category>
    </item>
    <item>
      <title>イチから始める OCaml</title>
      <dc:creator>SUZUKI Tetsuya</dc:creator>
      <pubDate>Thu, 23 Jan 2020 15:33:03 +0000</pubDate>
      <link>https://dev.to/szktty/ocaml-4d0o</link>
      <guid>https://dev.to/szktty/ocaml-4d0o</guid>
      <description>&lt;p&gt;※この記事は 2017年03月28日 に Qiita に投稿したものです。&lt;/p&gt;




&lt;p&gt;「&lt;a href="https://dev.to/szktty/ocaml-1o28"&gt;ゼロから始める OCaml&lt;/a&gt;」の続きです。元々は「やっぱり環境構築は無視できない道かなあ」と思っていたんですが、 &lt;a href="https://wandbox.org"&gt;Wandbox&lt;/a&gt; が Ocaml 、おっと &lt;strong&gt;OCaml&lt;/strong&gt; だった &lt;strong&gt;OCaml&lt;/strong&gt; に対応した (しかも &lt;a href="https://github.com/janestreet/core"&gt;Jane Street Core&lt;/a&gt; まで！) こともあり、環境構築は他のサイトなり記事なりを参考にしてもらうとして、 Ocaml 、おっと &lt;strong&gt;OCaml&lt;/strong&gt; だった &lt;strong&gt;OCaml&lt;/strong&gt; を始めたときに気になるであろうポイントをつつきたいと思います。&lt;/p&gt;

&lt;h2&gt;
  
  
  無料で読めるオススメのサイトはありますか？
&lt;/h2&gt;

&lt;p&gt;なんだかもう恐ろしい経歴の方々が実用視点で執筆された &lt;a href="https://realworldocaml.org"&gt;Real World OCaml&lt;/a&gt; があります (紙の書籍も出てます) 。よくも悪くも Core に大きく依存する内容で Wandbox と相性がよいです。&lt;/p&gt;

&lt;p&gt;英語がきつい？ Google 翻訳にかけると恐ろしいクオリティで日本語でおｋ。人力の和訳が必要なくなるレベルなんじゃないかな、これは...&lt;/p&gt;

&lt;h2&gt;
  
  
  関数の型の読み方
&lt;/h2&gt;

&lt;p&gt;OCaml の関数の型は "a -&amp;gt; b -&amp;gt; c" の形式で表されます。最後の "-&amp;gt;" が戻り値です。 "a -&amp;gt; b -&amp;gt; c" であれば、引数 a, b を渡すと c の型の値が返ってきます。&lt;/p&gt;

&lt;h2&gt;
  
  
  関数の戻り値の型が期待と違う
&lt;/h2&gt;

&lt;p&gt;前節で関数の型は "a -&amp;gt; b -&amp;gt; c" の最後の c が戻り値だと触れましたが、引数の数を間違えると c になりません。部分適用と言って、引数の数が満たされなくてもエラーにならないのではまりやすいポイントです。想定外の型エラーでビルドに失敗したら、該当の箇所の引数の数を確認してみましょう。&lt;/p&gt;

&lt;h2&gt;
  
  
  総称型の読み方
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;'a t&lt;/code&gt; という型は、 Java や TypeScript や Swift で言う総称型に相当します。 &lt;code&gt;'a t&lt;/code&gt; なら &lt;code&gt;t&amp;lt;a&amp;gt;&lt;/code&gt; です。アポストロフィ &lt;code&gt;'&lt;/code&gt; がつくのが型変数です。&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;code&gt;'a&lt;/code&gt; とか &lt;code&gt;t&lt;/code&gt; とかの 1 文字変数の意味
&lt;/h2&gt;

&lt;p&gt;OCaml の型名は &lt;code&gt;'a&lt;/code&gt; とか &lt;code&gt;t&lt;/code&gt; などの 1 文字の変数がよく使われます。これらの変数名は何の略語かと言うと、&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;型変数 &lt;code&gt;'a&lt;/code&gt;: ML 系の言語では a, b, c... とアルファベット順に続くのが慣習のようです。もちろん名前を付けたほうがわかりやすいので、そこはお好みで。&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;型 &lt;code&gt;t&lt;/code&gt;: type の略です。 &lt;code&gt;Module.t&lt;/code&gt; という型があったら、それは &lt;code&gt;Module&lt;/code&gt; モジュールに所属する型 &lt;code&gt;t&lt;/code&gt; を表します。&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;です。慣れないうちはわかりにくいかも。&lt;/p&gt;

&lt;h2&gt;
  
  
  ラベル付き引数とオプショナル引数
&lt;/h2&gt;

&lt;p&gt;関数の引数には名前 (ラベル) をつけることができます (Swift にもありますね) 。型宣言だと引数の前にある &lt;code&gt;f:&lt;/code&gt; がラベルです。注意すべきは、引数にラベルを付けて関数を呼び出す場合は &lt;code&gt;~&lt;/code&gt; をつけないといけません。関数 &lt;code&gt;f&lt;/code&gt; の型が &lt;code&gt;x:int -&amp;gt; y:int -&amp;gt; int&lt;/code&gt; だったら、コードは &lt;code&gt;f ~x:1 ~y:2&lt;/code&gt; と書きます。&lt;/p&gt;

&lt;p&gt;ラベルの前に &lt;code&gt;?&lt;/code&gt; があれば、それはオプショナル引数と言って、省略可能な引数です。詳しくはググるか本を読むかしてください。&lt;/p&gt;

&lt;h2&gt;
  
  
  コードの実行順序
&lt;/h2&gt;

&lt;p&gt;OCaml は型推論のある強い静的型付けの言語です。静的型付けと言えば Java や Haskell 、最近ですと Swift や TypeScript を思い浮かべる方が多いかと思います。これらの言語は宣言の順序にわりと融通がきいて、型やクラスの宣言の場所や順序はユーザーに一任されていることが多いです。&lt;/p&gt;

&lt;p&gt;「 OCaml も静的型付けの言語ですからそうだろう」と思いがちですが、実は OCaml のコードは &lt;strong&gt;上から順に&lt;/strong&gt; 評価されます。いいですね、 &lt;strong&gt;上から順に&lt;/strong&gt; です。次のように、依存する関数をあとから書いたコードはコンパイルできません:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight ocaml"&gt;&lt;code&gt;&lt;span class="c"&gt;(* 内容は適当 *)&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;g&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;g&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;正しくはこのように書きます。スクリプト言語みたいですね。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight ocaml"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;g&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;g&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;相互に依存する型なり関数なりを書きたい場合はどうするのかって？ &lt;code&gt;and&lt;/code&gt; で定義をつなぎます。詳しくは各自調べてください。&lt;/p&gt;

&lt;p&gt;ちなみに、関数に渡す引数の評価順序は &lt;strong&gt;不定&lt;/strong&gt; です。関数 f を &lt;code&gt;f x y z&lt;/code&gt; と呼び出したからと言って、引数の式が x, y, z の順に評価されるとは保証されません。&lt;/p&gt;

&lt;h2&gt;
  
  
  エントリーポイント
&lt;/h2&gt;

&lt;p&gt;他の静的型付け言語だと main が一般的なエントリーポイント (最近はマイクロソフトの長音付けルールを参考にしてます) ですが、 OCaml では特別なエントリーポイントはありません。トップレベルに書いた式が &lt;strong&gt;上から順に&lt;/strong&gt; 実行されます。&lt;/p&gt;

&lt;p&gt;ただし、トップレベルと関数定義内の式の文法は少し違い、区切り記号に &lt;code&gt;;&lt;/code&gt; だけでなく悪名高い &lt;code&gt;;;&lt;/code&gt; も使われます。ただし &lt;code&gt;;;&lt;/code&gt; は大抵の場合で省略可能で、言われるほど目にする機会はないと思います。私も滅多に書きません。&lt;/p&gt;

&lt;p&gt;トップレベルに式を書く際に &lt;code&gt;;;&lt;/code&gt; を省略する方法は、式の値を &lt;code&gt;let _ = ..&lt;/code&gt; と変数に代入するか、 &lt;code&gt;let () = ..&lt;/code&gt; のように unit とパターンマッチさせます (もちろん、式の値が unit でなければ型エラーです) 。ちょっと面倒なバッドノウハウですね。&lt;/p&gt;

&lt;p&gt;よければ &lt;a href="https://dev.to/szktty/ocaml-26o6"&gt;OCaml のエントリポイント&lt;/a&gt;も参照してください。&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;code&gt;;;&lt;/code&gt; の意味
&lt;/h2&gt;

&lt;p&gt;上で触れたキモさ抜群の &lt;code&gt;;;&lt;/code&gt; ですが、これも上で触れましたが、トップレベルの式には文法上必要な記号です。と言うのは、関数式とトップレベルの &lt;code&gt;let&lt;/code&gt; 式に終端記号がないからです。&lt;/p&gt;

&lt;p&gt;例えば次のようにエントリーポイントを書きたいとします:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let main () =
    (* 適当 *)
    f ()

main ()
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;このとき、最後の &lt;code&gt;main ()&lt;/code&gt; はどういう扱いになるのか？ OCaml の文法は改行に意味がないので、 &lt;code&gt;f ()&lt;/code&gt; にくっついて&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;f () main ()
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;という式に解釈されてしまいます。&lt;/p&gt;

&lt;p&gt;それなら式の区切りに使う &lt;code&gt;;&lt;/code&gt; でどうでしょうか:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let main () =
    f ();

main ()
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;やっぱり改行に意味はないので、このように解釈されます:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let main () =
    f ();
    main ()
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;code&gt;main ()&lt;/code&gt; が &lt;code&gt;main&lt;/code&gt; 関数内で呼ばれることになります。再帰関数に見えますが、 OCaml では &lt;code&gt;let rec&lt;/code&gt; で始めないと再帰関数として扱われませんので、それはそれでエラーです。この例はたまたま再帰の形になってエラーになりますが、エラーにならない場合もあり、はまりポイントになってしまうことがあります。バッドノウハウ以外の何物でもありませんが気をつけましょう。&lt;/p&gt;

&lt;p&gt;そういうわけで、トップレベルの終端記号である &lt;code&gt;;;&lt;/code&gt; を使えば問題は解決します。こうです:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let main () =
    f ()
;;

main ()
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;ただし、連続する &lt;code&gt;let&lt;/code&gt; 式なら &lt;code&gt;;;&lt;/code&gt; は省略可能です。こう書けます:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let main () =
    f ()

let () = main ()
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;ちなみに &lt;code&gt;let&lt;/code&gt; 式に &lt;code&gt;end&lt;/code&gt; のような終端記号を必須にすれば &lt;code&gt;;;&lt;/code&gt; は不要になりますが、 &lt;code&gt;end&lt;/code&gt; のないコードは快適でして、ほぼ省略可能な &lt;code&gt;;;&lt;/code&gt; を消すメリットは薄かったりします。&lt;/p&gt;

&lt;p&gt;こればかりはキモいけど仕方ないかもしれませんね。&lt;/p&gt;

&lt;h2&gt;
  
  
  Wandbox で Core を使う
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://wandbox.org/"&gt;Wandbox&lt;/a&gt; が OCaml + Core に対応したことで、わざわざ環境構築しなくてもさっと試せるようになりました。 Core を使う場合はこうします:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"Jane Street Core" のチェックボックスを有効にする&lt;/li&gt;
&lt;li&gt;コードの先頭に &lt;code&gt;open Core.Std&lt;/code&gt; を書く&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;これで Core のモジュールを使えるようになります。 Core は OCaml の付属ライブラリのモジュールを同名のモジュールで置換するので、例えば List と書くと Core.Std.List が参照されます。&lt;/p&gt;

&lt;p&gt;ただし、置換されるモジュール名や関数名は同じでも、 Core の API は引数のルールが OCaml 付属の API と違います。 Core の特徴は、&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;1 モジュールにつき中心的な型は 1 つで、 &lt;code&gt;t&lt;/code&gt; という名前で定義される&lt;/li&gt;
&lt;li&gt;第 1 引数の型はだいたい &lt;code&gt;t&lt;/code&gt; &lt;/li&gt;
&lt;li&gt;ラベルをよく使う&lt;/li&gt;
&lt;li&gt;多相バリアントをよく使う&lt;/li&gt;
&lt;li&gt;モジュール名の規則は "Foo_bar_baz" (文法上、先頭は大文字でないといけない)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;といったところです。最後のモジュール名などは「やっぱ OCaml の文法キモい」という悲鳴が聞こえますが、私なんかは「 CamelCase だと略語を大文字と小文字のどちらかにするかを考えるのが面倒くさい。 HTTP なのか Http なのかどっちがいいんだ」と思っちゃったんで、他の言語で例を見なくても "Foo_bar_baz" でいいじゃない、で済ませてます。&lt;/p&gt;

&lt;h2&gt;
  
  
  オブジェクト指向について
&lt;/h2&gt;

&lt;p&gt;OCaml の "O" は元々 "Objective Caml" の "O" であり (現在は略語ではない一単語の "OCaml" に改名されています) 、関数型とオブジェクト指向のハイブリッドでコードを書けます。&lt;br&gt;
もちろん OCaml の書籍でもオブジェクト指向について結構な量のページを割かれているので、普段オブジェクト指向言語を使っている人はまずそこから始めてみることが多いかもしれません。&lt;/p&gt;

&lt;p&gt;しかし、実際は &lt;del&gt;実際は大半のユーザーがオブジェクト指向を使ってないと思います。&lt;/del&gt; 大半の状況でオブジェクト指向を使わなくても大丈夫だと思います。決して OCaml のオブジェクト指向の出来が悪いのではなく、理由は簡単です。オブジェクト指向って &lt;strong&gt;意外と必要ない&lt;/strong&gt; からです。必要ない理由はめんどくさいので割愛します (コード書くうちにわかるでしょ) 。オブジェクト指向のコーディングを覚えなくても全然問題ないので、参考書の該当の章は飛ばしてもいいと思います。&lt;/p&gt;

&lt;h2&gt;
  
  
  ファンクター難しそう
&lt;/h2&gt;

&lt;p&gt;強力かつ複雑な、ファンクターという機能があります。ファンクターを簡単に言うと、コードを抽象化して大幅に無駄を減らせる (かもしれない) 機能です。なんですが、学習したてだとしばらくは必要ないはずです。まったく知らなくても問題ないです。「ここらへんは重複する処理が多くて抽象化できそう、でもやり方がわからない」と何度も痛感したら学ぶか、もしくは脳筋コピペで済ませてもいいと思います。余裕ができたらファンクターに取り組んでみましょう。ひとまずは動けばいいんです、動けば。&lt;/p&gt;

&lt;p&gt;私は Real World OCaml や日本語書籍も含めて読んでもなかなかわかりませんでした。「やっぱ難しいんだ...」などとあきらめないで！というか、「最初からファンクターがわからなくてもなんとかなるんだ」とか「おいそこのレビュアー、俺にファンクターを教える権利をやろう」とか、ポジティブに前向きに考えていただけたらと思います。&lt;/p&gt;

&lt;h2&gt;
  
  
  ガチで取り組むなら何から始めればいい？
&lt;/h2&gt;

&lt;p&gt;私も OCaml での業務経験はさほどないのであくまで個人的な意見ですが、コードを書く前にビルド環境の構築をおすすめします。&lt;/p&gt;

&lt;p&gt;幸い、よくも悪くも OCaml ユーザーは世界中に大多数存在するとは言えず、ライブラリやツールの候補も多くありません (しかし、メジャーなものはいずれもハイクオリティです) 。というか余程のヘビーユーザーでなければほぼ一択じゃないでしょうか。最低限次のツールを揃えれば大丈夫だと思います。&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;パッケージ管理に &lt;a href="https://opam.ocaml.org"&gt;OPAM&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;ビルドに &lt;a href="https://ocaml.org/learn/tutorials/compiling_with_omake.ja.html"&gt;OMake&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;非力な組み込みライブラリを補助するライブラリ。とりあえず Core を使っておけば間違いはないです。でかいのが難点。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;他にあるといいもの:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;生産性を上げるために &lt;a href="http://d.hatena.ne.jp/camlspotter/20081231/1230690789"&gt;OCamlSpotter&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;足りないライブラリを作る気合い&lt;/li&gt;
&lt;li&gt;(ﾟ∀ﾟ)人(ﾟ∀ﾟ)ﾅｶｰﾏ&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;がんばってください！&lt;/p&gt;

</description>
      <category>ocaml</category>
    </item>
    <item>
      <title>OCaml のエントリポイント</title>
      <dc:creator>SUZUKI Tetsuya</dc:creator>
      <pubDate>Thu, 23 Jan 2020 15:30:00 +0000</pubDate>
      <link>https://dev.to/szktty/ocaml-26o6</link>
      <guid>https://dev.to/szktty/ocaml-26o6</guid>
      <description>&lt;p&gt;※この記事は 2014年11月04日 に Qiita に投稿したものです。&lt;/p&gt;




&lt;p&gt;以前「&lt;a href="https://dev.to/szktty/ocaml-1o28"&gt;ゼロから始める OCaml&lt;/a&gt;」という記事を書いたのですが、その中で “Hello, world!” と出力するコードを例に挙げました。このコードは対話環境 (&lt;code&gt;ocaml&lt;/code&gt; コマンド) に入力しても、ファイルに保存してコンパイルしても、どちらでも無事に実行されます。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight ocaml"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="bp"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;printf&lt;/span&gt; &lt;span class="s2"&gt;"Hello, world!&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;code&gt;let () =&lt;/code&gt; は &lt;code&gt;let _ =&lt;/code&gt; としてもOKです。いずれにせよ、 &lt;code&gt;let () =&lt;/code&gt; から始まるこの式はエントリポイントなわけですね。&lt;/p&gt;

&lt;p&gt;しかし OCaml のコードを書いていると気が付きますが、 &lt;code&gt;let () =&lt;/code&gt; も &lt;code&gt;let _ =&lt;/code&gt; も単なるパターンマッチ、または単なる変数束縛です。なぜ単なる &lt;code&gt;let&lt;/code&gt; 式がエントリポイントになるんでしょうか。&lt;/p&gt;

&lt;p&gt;他の言語、特に OCaml と同系統の言語ではエントリポイントがどうなっているのか、ちょっと見てみましょう。&lt;/p&gt;

&lt;p&gt;まあ、じゃあ... Haskell で。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="n"&gt;main&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;putStrLn&lt;/span&gt; &lt;span class="s"&gt;"Hello, World!"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Haskell では &lt;code&gt;main&lt;/code&gt; 関数がエントリポイントとして実行されます。わかりやすいですね。&lt;/p&gt;

&lt;p&gt;F# ではこうです。 &lt;code&gt;EntryPoint&lt;/code&gt; 属性を指定した関数がエントリポイントとなります。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight fsharp"&gt;&lt;code&gt;&lt;span class="p"&gt;[&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;EntryPoint&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;]&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;
  &lt;span class="n"&gt;printfn&lt;/span&gt; &lt;span class="s2"&gt;"Arguments passed to function : %A"&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;
  &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;どちらの言語でもエントリポイントには専用の条件があります。 なぜ OCaml では単なる let がエントリポイントになるのか - もしトップレベルの &lt;code&gt;let () =&lt;/code&gt; や &lt;code&gt;let _ =&lt;/code&gt; が特別な扱いを受けるのであれば、私もマニュアルやら技術書やらで目にしていると思うのですが、どうもそんな覚えがありません。お前ろくに技術書なんか読まねえだろって？ うるせーよ。&lt;/p&gt;

&lt;p&gt;とすると...「なぜ単なる &lt;code&gt;let () =&lt;/code&gt; や &lt;code&gt;let _ =&lt;/code&gt; がエントリポイントになるのか？」も気になりますが、「なぜ他の &lt;code&gt;let&lt;/code&gt; による関数定義がエントリポイントにならない」んでしょうね？ そんなの当然だろ何言ってんの、と言われそうです。&lt;/p&gt;

&lt;p&gt;うーん、なんで当然なのかと言ったら、関数って呼ばれなきゃ評価されないからですよね。じゃあいつ呼ばれるのかと言ったら、そりゃ呼ばれたとき...などと繰り返しているとバカみたいですけど、正格評価とか遅延評価とか私も耳にしたことがあります。 Haskell は遅延評価ってのが有名ですね。&lt;/p&gt;

&lt;p&gt;エントリポイントの話が宙ぶらりんのままなんで、関数呼び出しがどっから始まるのかという問題はさておき、関数が呼ばれる可能性のある部分的な状況を考えてみます。ややこしいですけど、要は関数に渡す引数のことです。例えば次のような式がある場合、&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;f x y z
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;大抵の言語だと、引数 &lt;code&gt;x&lt;/code&gt; &lt;code&gt;y&lt;/code&gt; &lt;code&gt;z&lt;/code&gt; の式は左から順に評価されます。 Haskell ではわかりません。いや本当に。どっかで必要になったら初めて計算されるのが遅延評価なんで、この式だけではわかりません。関数 &lt;code&gt;f&lt;/code&gt; 内で &lt;code&gt;x&lt;/code&gt; &lt;code&gt;y&lt;/code&gt; &lt;code&gt;z&lt;/code&gt; の値が必要になったら評価されます。&lt;/p&gt;

&lt;p&gt;さて OCaml ではどうなのかと言うと、&lt;a href="http://www.fos.kuis.kyoto-u.ac.jp/~igarashi/OCaml/"&gt;プログラミング in OCaml&lt;/a&gt; にこんな一文を見つけました。 （「8.3 制御構造」、 164 ページ）&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;現在の実装では、後ろの引数から順に評価が行われるのですが、 OCaml の言語仕様としては引数の評価順序は未定義なので、...&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;えっ、今なんと？ &lt;strong&gt;OCaml の言語仕様としては引数の評価順序は未定義？&lt;/strong&gt; な、なんだってー！ コワイ！ 慌ててググってみると、&lt;a href="http://d.hatena.ne.jp/tatta/20091107/1257542947"&gt;二項演算式と let 式で評価順序が違う&lt;/a&gt;らしいじゃないですか。しかもキャミバ様、もとい神々の使者ラクダ天狗（いや逆では？）もこう言ってるじゃないすか！ やだー！&lt;/p&gt;


&lt;blockquote class="twitter-tweet"&gt;
&lt;p&gt;??「OCaml の関数引数等評価順序は左からでも右からでもない…未定！すまんな、本当にすまん。&lt;/p&gt;— 星のキャミバ様 (@camloeba) &lt;a href="https://twitter.com/camloeba/status/521564313757048833"&gt;2014, 10月 13&lt;/a&gt;
&lt;/blockquote&gt; 

&lt;p&gt;ここはドキュメントにあたらねば！ -&amp;gt; &lt;a href="http://ocaml.jp/refman/ch06s07.html"&gt;「評価順序は規定されていません」っつー文言が散見されます。&lt;/a&gt; うーむ、 mjsk 。&lt;/p&gt;

&lt;p&gt;と唸りながらドキュメントを眺めていたら、&lt;a href="http://ocaml.jp/refman/ch06s11.html#bnf--definition"&gt;モジュール式&lt;/a&gt;にこうありました。&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;各定義はストラクチャ内に現れた順に評価されます。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;OCaml のソースファイルはモジュールとしても扱われるので、えっと、つまり... &lt;code&gt;let&lt;/code&gt; 式は「上から順に評価される」ということ？ じゃあ冒頭の "Hello, world!" も順に評価されていただけで、 &lt;code&gt;let () =&lt;/code&gt; を二行書いたら二行とも評価されるってこと？ こ、こうか？&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let () = Printf.printf "1\n"
let () = Printf.printf "2\n"
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;





&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ ocaml prog.ml
1
2
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;なんと...評価された。はー、だから OCaml には特別なエントリポイントは必要なかったわけだ。まあ（たいしてコード書いてないけど）これまで特に困った試しもないので、問題ないんでしょうね。&lt;/p&gt;

&lt;h2&gt;
  
  
  追記：不定の評価順序
&lt;/h2&gt;

&lt;p&gt;評価順序についてコメントを頂きました。&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;別のところで書いたことがあるのですが、関数引数の評価順をあえて不定にするのにはそれなりの意味があります。ある特定の引数評価順に仕様を定めてしまうと、その評価順に依存した挙動のプログラムを書くことが堂々と可能かつ正当化されてしまいます。引数の評価順に依存したプログラムは複雑すぎるので書いて欲しくない場合、かつ依存しているかどうか静的に判定かつ禁止できない場合、言語設計者は評価順を積極的に不定にすることになります&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;なるほど、そういう理由があるんですね。で、ググってみたら &lt;a href="http://d.hatena.ne.jp/yohhoy/20120304/p1"&gt;C でも関数の評価順序は未規定&lt;/a&gt;じゃないですか。手元の本にも「引数の順序は指定されない」て書いてありました (演算子の式の評価順序も同じ) 。うわー、ずっと C 書いてたくせに今更知ったよ...&lt;/p&gt;

&lt;p&gt;まあ実は OCaml での評価順序を気にし始めたのも、 &lt;a href="https://github.com/esumii/min-caml/blob/master/parser.mly"&gt;MinCaml のソース&lt;/a&gt;をつい数日前に見たからなんですけどね。これまで OCaml の評価順序について考えたこともなかったよ (・ω&amp;lt;)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;| exp EQUAL exp
    { Eq($1, $3) }
| exp LESS_GREATER exp
    { Not(Eq($1, $3)) }
| exp LESS exp
    /* ここから比較演算子を &amp;lt;= の式に変換。 $1 と $3 の式の位置を逆にしてる */
    { Not(LE($3, $1)) }
| exp GREATER exp
    { Not(LE($1, $3)) }
| exp LESS_EQUAL exp
    { LE($1, $3) }
| exp GREATER_EQUAL exp
    { LE($3, $1) }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;よいこのみんな、勉強になったね！（お前だよ&lt;/p&gt;

</description>
      <category>ocaml</category>
    </item>
    <item>
      <title>ゼロから始める OCaml</title>
      <dc:creator>SUZUKI Tetsuya</dc:creator>
      <pubDate>Thu, 23 Jan 2020 15:24:29 +0000</pubDate>
      <link>https://dev.to/szktty/ocaml-1o28</link>
      <guid>https://dev.to/szktty/ocaml-1o28</guid>
      <description>&lt;p&gt;※この記事は 2014年03月08日 に Qiita に投稿したものです。&lt;/p&gt;

&lt;p&gt;※追記：オンラインで OCaml 含む様々なプログラミング言語を試せる &lt;a href="https://wandbox.org"&gt;Wandbox&lt;/a&gt; というサービスがあります。強力な基礎ライブラリの &lt;a href="https://opensource.janestreet.com/core/"&gt;Jane Street Core&lt;/a&gt; も使えるので、そちらを使うとこの記事はほぼ無意味です。&lt;/p&gt;




&lt;p&gt;OCaml に興味津々のみなさんこんにちは、 OCaml ビギナーです。さて、 OCaml とは（ry&lt;/p&gt;

&lt;p&gt;ググればわかるような説明はさておき、そこのあなた、 "Ocaml" とキーを叩いてググる暇があるなら（あっ、 &lt;strong&gt;"OCaml"&lt;/strong&gt; でした！）、いますぐターミナルを開いて &lt;code&gt;brew install ocaml&lt;/code&gt; しましょう。やれってば。案ずるより産むが易しと言うではありませんか（ Windows でしたか？ &lt;a href="https://bitbucket.org/camlspotter/ocaml-zippy-tutorial-in-japanese/src/7e5943ed17edf58f370c34feeb218a30cc09143f/random_memo.rst?at=default#rst-header-ocaml-unix"&gt;残念ながら Windows での OCaml は茨の道のようです。&lt;/a&gt;なんとか Unix 環境を用意してください）。おや、「 OCaml は仕事で使えるの？」「関数型言語って難しいんじゃない？」という心の声が聞こえましたが、アーアーキコエナーイ。はいはい、ググるだけ無駄です。どこを探しても、今のあなたの役に立つ情報なんかありませんよ？（おっと、誰か来たようだ）&lt;/p&gt;

&lt;p&gt;...&lt;/p&gt;

&lt;p&gt;はい、 &lt;code&gt;brew install ocaml&lt;/code&gt; しましたか？ してない？ しないの？ なんで？ ああ、インストール済みでしたか、早く言ってくださいよ（ちなみに OCaml の最新バージョンは、これを書いている時点で 4.01.00 です）。じゃあ、次にビルドツールの OMake をインストールするために &lt;code&gt;brew install omake&lt;/code&gt; して...あっ、 Homebrew に OMake なかった...。もし手間を惜しまないなら &lt;a href="https://dev.toopam%20ocaml"&gt;OPAM という OCaml 用のパッケージ管理ツールをオススメします&lt;/a&gt;が、セットアップが終わるまでになかなか時間を食います。私のような環境構築をめんどくさがるタイプのビギナーにとっては、これが意外と生きる気力をスポイルするんですよね。技術者たる者、そんなこっちゃいかんと日々思っているのですが。まあ準備運動で力尽きないためにも、最初はインタプリタと標準ライブラリだけで学んでもいいでしょう（コンパイラもあります。後述）。&lt;/p&gt;

&lt;p&gt;では、 5 分もあればできる恒例の Hello, world にトライしたいと思います。え？ 手垢のついたつまんねーサンプルはやめろ？ いやいや、ビギナーってのは Hello, world と出力するまでの手順すらわからないからビギナーなんです。どんな言語でも、まずはそこから調べないとね。というわけで、 &lt;code&gt;main.ml&lt;/code&gt; という名前でファイルを作って、次のコードをコピペしてください。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let () = Printf.printf "Hello, world!\n"
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;あれ？ Qiita のシンタックスハイライトに OCaml がないよ？（このハイライトは Haskell らしい）まあいいや、このファイルを &lt;code&gt;ocaml&lt;/code&gt; の引数に渡して実行してみましょう。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ ocaml main.ml
Hello, world!
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;出力されました！やったね！&lt;/p&gt;

&lt;p&gt;...これでおしまいにしちゃうと不親切ですかね。ぱっと見て、次の疑問が頭に浮かんだかと思います。&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;let () =&lt;/code&gt; とは何ぞや？&lt;/li&gt;
&lt;li&gt;OCaml はインタプリタなの？&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;let () =&lt;/code&gt; とは何か？ あー、うん、気にしなくていいです。この右辺にコードを書いておくと、プログラムの起動時に実行されるとだけ覚えておけばいいです。&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ocaml&lt;/code&gt; コマンドは&lt;del&gt;インタプリタですが&lt;/del&gt;（&lt;a href="https://twitter.com/camloeba/status/442989900669800448"&gt;インタプリタとは言わないとツッコミ頂きました&lt;/a&gt;）&lt;a href="http://ocaml.jp/Chapter%209%20%E3%83%88%E3%83%83%E3%83%97%E3%83%AC%E3%83%99%E3%83%AB%E5%AF%BE%E8%A9%B1%E7%92%B0%E5%A2%83%20(ocaml)"&gt;トップレベル対話環境&lt;/a&gt;で、引数にファイルを指定すると面倒なビルド手続きなく実行してくれます。ただ OCaml にはネイティブコードコンパイラ &lt;code&gt;ocamlopt&lt;/code&gt; も用意されているので、実際の開発ではこちらを使います。実行速度が違いますからね。その他にバイトコードコンパイラ &lt;code&gt;ocamlc&lt;/code&gt; も含まれているのですが、まあ触ってみる程度なら &lt;code&gt;ocaml&lt;/code&gt; を、通常の開発では &lt;code&gt;ocamlopt&lt;/code&gt; を使えばいいんだと思います。&lt;a href="http://d.hatena.ne.jp/camlspotter/20121204/1354588576"&gt;続きは Web で！&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;さあ、これで OCaml プログラムを動かす方法を一つ覚えました。明日からは好き放題 OCaml を書けますね。うん？ main.ml が膨らんだときにファイルを分割するにはどうすればいいかって？ そうですねえ、そこまで困ってから考えればいいと思いますよ。&lt;/p&gt;

</description>
      <category>ocaml</category>
    </item>
  </channel>
</rss>
