From: ttate@... Date: 1999-03-11T23:52:16+09:00 Subject: [ruby-dev:6233] Re: Range (Re: array[last..first] (Re: Subseq of Array)) 立石です。 Date: Thu, 11 Mar 1999 20:45:42 +0900 From: keiju@rational.com (石塚圭樹 ) keiju> 集合ではなくて順序集合かも. keiju> どっちが良いか悩みますが, keiju> R[1, 10] => {1,2,...,10} keiju> R[10, 1] => {10,9,...,1} keiju> であれば, 順序集合ですね. 僕はとりあえずSetでもいいかと思っています。おそらく問題 となるのは(1)現在の値から次の値をどうやってもとめるかと いうことと、(2)いつ繰返しが終了するのかということだと考 えています。 僕自信の答えは(1)についてはProc(あるいは疑似的なProc)で 実現でき、(2)についてはSetに属さない値を得たときに終了 と言う感じなのです。 よって、整数集合だけでなくrational,float,stringも扱って しまおうという意図があります。 また、僕のイメージではSetはそれが属するか否かを判断するメソッド (include?)と集合演算子のみで表現可能です。そうすることであ えて集合の要素すべてをSetが持つ必要性がなくなり無限の要素を もつ集合すら表すことが可能です。そうするとWhileも表現可能と なり、While,Forをより一般的に表現でき、しかも集合と範囲をある程度 関わりをもって表現できるのではないかと考えた次第です。 具体的には以下のような感じです。 class Set def initialize(f) # fはtrue/falseを返すProcオブジェクト @mem_p = f end def include?(mem) @mem_p.call(mem) end def conj(s) @mem_p = proc{|mem| s.include?(mem) and include?(mem)} end def disj(s) @mem_p = proc{|mem| s.include?(mem) or include?(mem)} end end こういう集合の定義の仕方で class Range < Set def initialize(min,max) super(proc{|i| min <= i && i <= max}) end end class Loop # rangeではなくsetであるのがミソ def initialize(initval, set, nextf) @cur = @init = initval @set = set .... end def each @cur = @init while( @set.include?(@cur) ) yield(@cur) @cur = nextf.call(@cur) end end end となって例えば for i in 0..10 hogehoge end は r = Range.new(0,10) l = Loop.new(0,r,proc{|i| i + 1}) l.each{|i| hogehoge } と表現できます。 keiju> 1..2 + 5..6 keiju> のような, 直和(合併)された集合なども表せると良いですね. これも可能となります。 ;; 長い文章になってしまった、、、、 Takaaki Tateishi