昨日全く寝ずに、そのまま東京Node学園祭に行き(はっきりいって くだらなかった.同じ学科の連中の発表のほうがもっと刺激的だ) その帰りの足でアキバで小林ゆうを見た.遠近法の効果により 豆粒ほど小さかった.
今年の目標を決めた.あと1ヶ月半だけなのだから具合がいい. 人とあまり馴れ馴れしくしないこと. 自立すること.
ググっても正規表現マッチしか出てこないけれど、関数型言語 におけるパターンマッチのはなし.
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
を書く、などというお題に対して 使ったトリックだ.