Mon Nov 19 02:17 2012

昨日全く寝ずに、そのまま東京Node学園祭に行き(はっきりいって くだらなかった.同じ学科の連中の発表のほうがもっと刺激的だ) その帰りの足でアキバで小林ゆうを見た.遠近法の効果により 豆粒ほど小さかった.

今年の目標を決めた.あと1ヶ月半だけなのだから具合がいい. 人とあまり馴れ馴れしくしないこと. 自立すること.


JavaScript におけるパターンマッチ.

ググっても正規表現マッチしか出てこないけれど、関数型言語 におけるパターンマッチのはなし.

type Nat = Zero | Succ of Nat

match n with
  | Zero -> "zero"
  | Succ(Zero) -> "one"
  | _ -> "takusan"

これはswitch文以上につよい. 入れ子にできるから. これをjavascriptでどう表現するか. 1.8の構文を用いれば、let による分割代入ができて、

パターンマッチだ!とか書いてる記事があるけれど,
私の知ってる パターンマッチ という言葉遣いと違う.
その記事がいうのは,

let [[a,b],c,d] = [[1,2],3,4]

が可能という意味で、それはOCamlでは

match [[1;2];3;4] with
  | (a::b::[])::c::d::[] -> ...
  | _ -> failwith ""

とまあ確かにパターンマッチでよくやる.

私がやりたいパターンマッチは最初にかいたやつ. どう表現するか.

私が昨日一昨日発見して今気に入ってるのは オブジェクトのキーにパターンを列挙するもの. パターンマッチのパターンは有限に列挙するのだから これは可能だ.

match["Zero"] = "zero"
match["Succ(Zero)"] = "one"
if (n in match) match[n];
    else "takusan";

ほら、できた. 問題は、オブジェクトのキーは処理系によって 文字列型にキャストされることであり、 上の例なら Succ(Zero) というデータ構造(これも もちろんjavascriptでうまく定義しなければならない) がどう文字列にキャストされるかを知って置かなければ ならないこと. いっそのこととして私はデータ構造を文字列で持っておく ことにした.

これはまた変態的と言われるかもしれないが、 パターンマッチの when も表現できる.

match n with
  | _ when n%2=1 -> "odd"
  | _ -> "even"

を次のように

  match[true] = "odd"
when = n%2 == 1;
if (when in match) match[when];
    else "even";

はじめ、

exp == Int ? exp.val :
exp == Float ? exp.val :

みたいに書いててそれをパターンマッチだと言い張ってた のだけれど、ただswitch文を式として書いてるだけだと 気づいたし見た目が最悪なので先のものを思いついた.

if を使わずに fizzbuzz を書く、などというお題に対して 使ったトリックだ.