パスワードを忘れた? アカウント作成
512929 journal

rutoの日記: Rubyでcase文はパターン側の===演算子を呼ぶ

日記 by ruto

Haskellを使っているとパターンマッチ脳になってしまう。
するとRubyでもパターンマッチが使いたくなる。
Rubyではcase文(Cでいうところのswitch文)は===という演算子を使って場合分けをするというのを思い出して、

class Hoge
  ...
  def ===(pattern)
  ...
  end
  ...
end
 
case Hogeのインスタンス
when パターン
  ...
end

とやったのだがどうも上手くいかない。調べてみるとHogeで定義した===演算子が呼ばれていない。
Rubyのリファレンスマニュアルを見ると、「Hogeのインスタンス」の方ではなく「パターン」の方の===演算子が呼ばれるらしい。なので

class HogePattern
  ...
  def ===(hoge)
  ...
  end
  ...
end
 
case Hogeのインスタンス
when HogePattern::new(...)
  ...
end

としたら無事動いた。

よく考えてみるとこの設計は結構センス良いと思った。この設計なら別のPatternクラスを作ることによってHogePatternとは別の意味でマッチするようなパターンをいくらでも作れる。これがもしHoge側の===を使うようになっていたら1種類の意味でのマッチしか利用できない。

あとはパターンマッチしたときに変数が束縛されればいいのに。

myCase(Hogeのインスタンス).when(HogePattern::new(... VAR_PATTERN ... VAR_PATTERN ...) do |x, y|
end.when(パターン) do |a, b, c|
end.endCase

みたいなのを実装すればいいのか?
パターンはオブジェクトを受けとって配列を返す感じで。VAR_PATTERNは与えられたオブジェクトだけを含む配列を返す。

ちなみによく関数型言語とかで使われているパーザーコンビネーターもこんな感じで作られています。

この議論は賞味期限が切れたので、アーカイブ化されています。 新たにコメントを付けることはできません。
typodupeerror

弘法筆を選ばず、アレゲはキーボードを選ぶ -- アレゲ研究家

読み込み中...