Hatena::Grouphackathon

zrail (a.k.a. tobira17, h14i, ...) の Learning Log

2017-06-09

[][][]ML書いててついた変な癖 03:07 ML書いててついた変な癖 - zrail (a.k.a. tobira17, h14i, ...) の Learning Log を含むブックマーク はてなブックマーク - ML書いててついた変な癖 - zrail (a.k.a. tobira17, h14i, ...) の Learning Log

  • レコードを使わない
    • リスト、タプル、ヴァリアント。このあたりだけで何でもやろうとしてしまう。レコード使ったほうがすっきり書けるときもあるんだろうな、気付いてないだけで。
  • 末尾呼び出し
    • 明らかに深くネストしないような関数まで末尾呼び出しにしようと頑張る。
  • 内部関数の量産
    • 上の末尾呼び出しに関連して、アキュムレータを隠そうとした結果、大概の関数に内部関数。
  • ML 以外の言語でも ML っぽい書き方
    • まぁこれはプログラミングスタイルをまだ消化できてないというかプログラマの麻疹というか。

2017-05-21

[][][]シンタックスファイルの作成 for OCaml 23:44 シンタックスファイルの作成 for OCaml - zrail (a.k.a. tobira17, h14i, ...) の Learning Log を含むブックマーク はてなブックマーク - シンタックスファイルの作成 for OCaml - zrail (a.k.a. tobira17, h14i, ...) の Learning Log

割と地獄。

いや自分のスタイルだけは正しくハイライトとフォールドできる、みたいな奴ならそんなに大変じゃないんだけど、汎用っぽいのを書こうとするとなぁ。

僕はばんばんターミネータを置く派なので……。

外部のパーサでシンタックスファイルの生成してもらって適切なタイミングで読み直すとかしたいレベル。

2016-08-21

[][] どうでもいいメモ 01:36  どうでもいいメモ - zrail (a.k.a. tobira17, h14i, ...) の Learning Log を含むブックマーク はてなブックマーク -  どうでもいいメモ - zrail (a.k.a. tobira17, h14i, ...) の Learning Log

let f = function
    [] -> 0
  | _ :: _ -> 1
;;
(* とか *)
let f x = match x with
    0 -> true
  | _ -> false
;;

みたいな書き方と

let f = function
  | [] -> 0
  | _ :: _ -> 1
;;
(* とか *)
let f x = match x with
  | 0 -> true
  | _ -> false
;;

みたいな書き方ありますよね。'|' の書き方。

見た目以外の差ってあるんすかね?

一行で書くときは上のほうが自然ですよね。

let f = function [] -> 0 | _ :: _ -> 1;;

2017-03-26 追記

Camlのスタイルガイドに「最初のパターンにも書け」って書いてあったし、ギッハブとかで見てもどのマッチでも(コンストラクタとかも)書くのが普通って慣習っぽいな。


ところでStandard MLだと上みたいな余分な'|'は置けないみたいですね。datatypeは知らん。

fun f l = case l
  of [] => 0
   | _ => 1;
(* とか *)
fun f [] = 0
  | f _ = 1;

みたいに書く(っぽい)。

もしかしたら処理系によるのかも知れない(どこかで見たような気がするけど、OCamlと混同しているような気もする)。

一応SML/NJ, MLKit, Mltonは試したけど駄目だったので言語仕様的には不正だとは思うけど。

2009-08-17

[][]プログラミングの基礎 第 8 章 レコード 00:02 プログラミングの基礎 第 8 章 レコード - zrail (a.k.a. tobira17, h14i, ...) の Learning Log を含むブックマーク はてなブックマーク - プログラミングの基礎 第 8 章 レコード - zrail (a.k.a. tobira17, h14i, ...) の Learning Log

今回はレコードの話。

8.2 レコードの構文

注意。

# {namae = "asai"; tensuu = 70; seiseki = "B"}::
- : gakusei_t = {namae = "asai"; tensuu = 70; seiseki = "B"}

という例が最初に示されているけど、以下のように先に型の定義をしないとエラーが出るみたい。

# type gakusei_t = {name:string; score:int; grades:string};;
type gakusei_t = { name : string; score : int; grades : string; }
# {name = "asai"; score = 70; grades = "B"};;
- : gakusei_t = {name = "asai"; score = 70; grades = "B"}

本文中でも書いてあったんだけど、見落としてた。

どう書いても実行出来ないからおかしいなーと思ったら 8.5 節で型の定義はやるのね。

先に型定義の構文をやって欲しかったな。

8.3 レコードとパターンマッチ

タプル*1の場合とほぼ一緒。

パターン変数の決め方だけが違って、タプルの場合は構造的に?パターン変数の名前の割り当てが決まるけど、レコードは自分でフィールドにパターン変数の名前を決める。

8.4 そのほかの記法
  • フィールド名とパターン変数名は同じでも良い
  • パターン変数ではフィールドを省略出来る
  • 「レコード . フィールド」という書き方でも値は取り出せる( C の構造体みたいな感じ )
8.5 ユーザーによる型定義

型定義の例。

type gakusei_t = {
  name : string;
  score : int;
  grades : string;
};;

最後のフィールドの後のセミコロンは省略出来るみたい。

フィールド名の重複は不可。


まだ途中だけど今日はここまで。

*1:少年オッカムルの第五話で学んだ言葉!

2009-08-15

[][]プログラミングの基礎 第 7 章 組とパターンマッチ 21:53 プログラミングの基礎 第 7 章 組とパターンマッチ - zrail (a.k.a. tobira17, h14i, ...) の Learning Log を含むブックマーク はてなブックマーク - プログラミングの基礎 第 7 章 組とパターンマッチ - zrail (a.k.a. tobira17, h14i, ...) の Learning Log

少し間が空いたけど、再開する。

7 章から 9 章まではデータ構造の話みたい。

7.1 組の構文

2 つ以上の様々な型の値を組み合わせて「組」というデータ構造を表現出来る。

構造体みたいな感じ?

# (3.14, 2.71);;
- : float * float = (3.14, 2.71)
# (10, "str");;
- : int * string = (10, "str")
# (1, 'a', false);;
- : int * char * bool = (1, 'a', false)
# ((((3.13, 1), 1), 3), true);;
- : (((float * int) * int) * int) * bool = ((((3.13, 1), 1), 3), true)
7.2 パターンマッチ

パターンマッチの構文

matchwith
  パターン ->

注意。

  • パターン変数は互いに異なる変数でなくてはならない
  • パターン変数と与えられる組の型は同じでなくてはならない
# let test = (1, 2, 3);;
val test : int * int * int = (1, 2, 3)
# match test with
    (a, b) -> a + b;;
Characters 20-26:
      (a, b) -> a + b;;
      ^^^^^^
Error: This pattern matches values of type 'a * 'b
       but is here used to match values of type int * int * int
7.3 構造データに対するデザインレシピ

組を引数に取る関数はほぼ必ず組の要素を取り出す match 文から始まるはず。だからテンプレートを用意しておけば便利、という話。