OCaml - homma/homma.github.com GitHub Wiki
- OCaml チュートリアル
- お気楽 OCaml プログラミング入門
- Real World OCaml
- User's Manual
- Developing application with Objective Caml
エントリーポイントが必要なのか、という気もしますが...
"let () = " でも "let _ = " でも、どちらでも良い
let () = <main program>
let _ = <main program>
配列アクセスのリテラルはないみたい
String.get "foo" 0;;
# 0,0n,0l,0L;;
- : int * nativeint * int32 * int64 = (0, 0n, 0l, 0L)
# Int32.add 1l 2l;;
- : int32 = 3l
# Int32.mul 3l 4l;;
- : int32 = 12l
# Int32.sub 0l 10l;;
- : int32 = -10l
# Int32.div 0l 3l;;
- : int32 = 0l
# Int32.div 0l 0l;;
Exception: Division_by_zero.
# 2. ** 8.
;;
- : float = 256.
- OCaml's exponential operator uses float for its arguments.
2 進数、8 進数、16 進数の表記方法が用意されている
# 0b1, 0o7, 0xF;;
- : int * int * int = (1, 7, 15)
# 0b11 + 0o77 + 0xFF;;
- : int = 321
便利
参考 : Input / Output
まずは print_endline と read_line から。
入出力チャネルは stdin, stdout, stderr を使用可能。
# stdin, stdout, stderr;;
- : in_channel * out_channel * out_channel = (<abstr>, <abstr>, <abstr>)
output_char
# output_char stdout 'a';;
a- : unit = ()
output_string
# output_string stdout "こんにちは\n";;
こんにちは
- : unit = ()
output
# output stdout "12345" 0 3;;
123- : unit = ()
print_string
# print_string "こんにちは\n";;
こんにちは
- : unit = ()
print_endline
# print_endline "こんにちは";;
こんにちは
- : unit = ()
# print_endline @@ string_of_int 0;;
0
- : unit = ()
print_int
# print_int 0;;
0- : unit = ()
print_newline
# print_string "1: ";print_newline ();print_string "2: ";;
1:
2: - : unit = ()
prerr_endline
# prerr_endline "Error: watch out!";;
Error: watch out!
- : unit = ()
prerr_bytes, prerr_char, prerr_float, prerr_int, prerr_newline, prerr_string は省略
Printf.printf
# Printf.printf "%s\n" "こんにちは";;
こんにちは
- : unit = ()
input_char
# let a = input_char stdin;;
a
val a : char = 'a'
input_line
# let ln = input_line stdin;;
hello
val ln : string = "hello"
input
# let buf = "12345";;
val buf : string = "12345"
# input stdin buf 1 2;;
ab
- : int = 2
# buf;;
- : string = "1ab45"
read_line
# let ln = read_line ();;
hello
val ln : string = "hello"
-
Built-In Data Types
- 配列は使わないのかな(書きづらそうな記法が割り当てられている)
何も考えなくとも、複数行文字列を作成できる。
一行にまとめる時は \n でつなぐ。
# {|
foo
bar
baz
|}
;;
- : string = "\nfoo\nbar\nbaz\n"
# "
foo
bar
baz
"
;;
- : string = "\nfoo\nbar\nbaz\n"
Quoted String は、ヒアドキュメント的な機能のようです
# {|foo|};;
- : string = "foo"
{tag|string|tag} とすると、マッチする tag のチェックが行われるので、以下のようなことができる。
# {tag|foo|};;|tag};;
- : string = "foo|};;"
-
OCaml をカジュアルに使いづらい原因の一つ
- 今の時代に、Latin-1 決め打ちの文字列は辛い
- 普通の言語なら、Modernization の名の下に一番最初に修正される箇所
-
- UTF-8 対応は本当にその通り
-
- ありがたい情報
$ vi ~/.ocamlinit
let printer ppf = Format.fprintf ppf "\"%s\"";;
#install_printer printer
-
fun1 @@ fun2 @@ fun3 arg で、fun1 (fun2 (fun3 arg)) の意味
-
fun1 arg |> fun2 |> fun3 で、fun3 (fun2 (fun1 arg)) の意味
print_endline @@ string_of_int 0;
string_of_int 0 |> print_endline;;
- @@ は ML の o や Haskell の . に相当
- 良い感じ
$ brew install ocaml
$ brew install opam
$ opam init
$ echo 'eval `opam config env`' >> ~/.profile
$ . ~/.profile
S 式的なものが出力される
$ ocaml -dlambda
# let foo = "foo";;
(let (foo/1360 = "foo") (apply (field 1 (global Toploop!)) "foo" foo/1360))
val foo : string = "foo"
ocaml toplevel
- そもそも行編集機能がない
utop
- メタキー打ちづらい
- 余計な表示がある
- メンテナー募集中
rlwrap
- マルチライン編集ができない(-m newline は期待しているのと動きが異なる)
- 補完ができない
- 個人的に readline を使いたくない(GNU が戦略に利用した経緯があるため)
ledit
- 開発終了している模様
- https://github.com/diml/utop
- https://github.com/realworldocaml/book/wiki/Installation-Instructions
- rlwrap よりも utop を使用することが推奨されているみたい
- core もインストールが推奨されている
$ opam install core utop
$ utop
-
#utop_bindings;; するとキーバインドを確認できる
- 大体は普通の emacs 風のキーバインド
-
utop は微妙な感じ。センス!
- キーワードや変数を補完してくれる
-
macOS だとメタキーが使えない
- Terminal.app の設定で「メタキーとして Option キーを使用」にチェックを入れると、Option キーがメタキーになる
-
Ctrl-P で上の行に移動できるけど、一番上の行にいる時に、一つ前のコードに移動できない
- Opt をメタキーにして、Opt-P を使用することは可能ですが、Opt-P は押しづらい
-
全角文字には対応していない
- カーソルの位置は半角文字の文字数で決まっているみたい
-
不要な情報が表示される
- 時刻が入っている行は不要
インストール
$ brew install rlwrap
$ echo 'alias ocaml="rlwrap ocaml"' >> ~/.profile
アンインストール
$ brew uninstall rlwrap readline
$ vi ~/.profile
# alias を消す
- rlwrap は行単位での編集しかできない(;; 単位で戻れない)
- シンボルの補完ができない