Commits

camlspotter  committed e912745

update

  • Participants
  • Parent commits 0ca1414

Comments (0)

Files changed (1)

File random_memo.rst

 関数自体の型での引数の型と、関数定義内部での引数の型が異なるのに注目。
 上の関数の型では ``?foo:int`` になっているが、 ``foo`` は定義内部では ``int option`` になる。
 
+オプショナル引数を持つ関数を受け取る高階関数の扱い
+-------------------------------------------------------------------
 
+``f ~l:e`` というラベル付き引数の関数適用、これをコンテクストが不明な場合
+コンパイラはどう考えるかという問題。
+
+二つの可能性がある。
+
+* ``l`` という普通の(オプショナルでない)ラベル引数を持つ関数 ``f`` の適用
+* ``?l`` というオプショナルなラベル引数を持つ関数 ``f`` の適用
+
+この二つの場合は ``f`` に要求される型が異なる。そのため::
+
+    let h f e = f ~l:e
+
+という関数には二つの異なる型付けが考えられる。これは主型付けが失われることを
+意味するので ML の型システムとして大変によろしくない。
+元凶はオプショナル引数の適用に、普通のラベル引数の適用と同じシンボルを
+使ってしまっていることなのだが、まあそれはそれで便利である。
+
+OCaml ではこの問題を、文脈上ではっきりしないラベル付き引数の
+非オプショナル/オプショナルは、全部非オプショナルに倒すということで
+解決している。すなはち、上の式では ``~l`` は非オプショナルである::
+
+    let h f e = f ~l:e;;
+    val h : (l:'a -> 'b) -> 'a -> 'b = <fun>   (* l の前に ? がついていない *)
+
+ではこのような定義で ``l`` はオプショナルなんだけど、という際にはどうするか。
+コンパイラにその旨ヒントの文脈を与える::
+
+    let h (f : (?l:'a -> 'b)) e = f ~l:e;;
+    val h : (?l:'a -> 'b) -> 'a -> 'b = <fun>
+
+もしくは、 ``~l`` を使わずに ``?l`` で明示する::
+
+    let h f e = f ?l:(Some e);;
+    val h : (?l:'a -> 'b) -> 'a -> 'b = <fun>
+
+まあこういうことからも OCaml は型推論の完全性を目指しておりーとかは
+寝言だという事がわかるだろう。
 
 η expansion を簡単に書く
 ===============================================
 が ``let f = fun x -> x |> (.....)`` に展開されるようなマクロを書けば良い。
 どうやって書くか?そりゃあんたに任せる。
 
+``bool`` とか抽象的すぎる時は使わない
+==========================================================
+
+例えば、関数が bool を返す。でそれが関数操作の成功か失敗かを表しているらしい。
+どっちだ?知るかよ!! true は成功を意味するのか、それともエラー存在を意味するのか
+書いているお前にしかわからないし、書いたお前もすぐに忘れる。なんで::
+
+    type result = Success | Failure
+
+にしないのか。
+
+極論するとわけわかんない抽象的な値を返される位なら元から返り値は unit 
+にしてエラーは exception で上げてもらうほうがよほどマシかも知れぬ。
+
+わざわざ ``result`` 型を定義するのが面倒なら OCaml には polymorphic variant
+があるから ```Success`` や ```Failure`` を返せば良い。 ```Success``
+```Failure`` が長いんなら ```Ok`` と ```NG`` でエエやろちょっとは頭使って
+他人にやさしいコード書けやヴォケ。
+
+右か左かで ``bool`` とか死ねってことだ。わかるな?
+
 OCamlYacc オワコン。Menhir を使え
 ======================================