次の要素と前回の要素を伴った反復

eachで回してるときの次の要素がほしい - Greenbear Diary (2007-06-12)
http://mono.kmc.gr.jp/~yhara/d/?date=20070612#p04

Xtalでは外部イテレータでの反復となるので、割とこういうのも楽に書けるように出来ます。

// 前回の値を伴うイテレータを返す
Iterator::with_prev: method(){
  return fiber{
    prev: null;
    this{
      yield prev, it;
      prev = it;
    }
  }
}

// 前回と次回の値を伴うイテレータを返す
Iterator::with_prevsucc: method(){
  return fiber{
    prev: null;
    prev2: null;
    first: true;
    this{
      if(first){
        prev = it;
        first = false;
        continue;
      }
        
      yield prev2, prev, it;
      prev2 = prev;
      prev = it;
    }
    yield prev2, prev, null;
  }
}

array: [5, 6, 7, 8];
array.each.with_prev{ |prev, it|
  [prev, it].p;
}
// [null,5]
// [5,6]
// [6,7]
// [7,8]

array.each.with_prevsucc{ |prev, it, succ|
  [prev, it, succ].p;
}
// [null,5,6]
// [5,6,7]
// [6,7,8]
// [7,8,null]

// Xtalでは、with_prevsuccの返り値もイテレータとなるので、さらにwith_indexをつけたりも
array.each.with_prevsucc.with_index{ |idx, prev, it, succ|
  [idx, prev, it, succ].p;
}
// [0,null,5,6]
// [1,5,6,7]
// [2,6,7,8]
// [3,7,8,null]