6.64. kink/iter/ITER¶
6.64.1. iter型¶
“iter”は“iterator”の略語である。iterは有限長、または無限長の値のストリームである。
iterはifunのラッパである。ifunについてはkink/iter/IFUNを見よ。
6.64.1.1. Iter.ifun¶
ifunメソッドは、Iterがラップしているifunを戻す。
例
:IFUN.require_from('kink/iter/')
:Num_iter <- 5.times
Num_iter.each{(:N) stdout.print_line(N.repr) }
# => 0 1 2 3 4
:nums <- Num_iter.ifun
IFUN.each($nums){(:N) stdout.print_line(N.repr) }
# => 0 1 2 3 4
6.64.1.2. Iter.each($consume)¶
eachはIterの各要素について$consumeを呼び出し、最後の$consumeの戻り値を戻す。
もしIterが要素を持たない場合、eachはnadaを戻す。
事前条件
$consumeはひとつの引数を取る関数でなければならない。
例
3.times.each{(:E)
stdout.print_line(E.repr)
}
# Output:
# 0
# 1
# 2
6.64.1.3. Iter.map($transform)¶
mapは、N番目の要素がtransform(IterのN番目の要素)であるようなiterを戻す。
事前条件
$transformはひとつの引数を取らなければならない。
例
:ITER.require_from('kink/iter/')
:Ns <- ITER.of(1 2 3 4)
:Doubles <- Ns.map{(:N) N * 2 }
Doubles.each{(:D)
stdout.print_line(D.repr)
}
# Output:
# 2
# 4
# 6
# 8
6.64.1.4. Iter.concat_map($to_iter)¶
concat_mapは、to_iter(Iterの要素)の戻り値のiterを結合したiterを戻す。
事前条件
$to_iterは引数をひとつ取り、iterを戻さなければならない。
例
:ITER.require_from('kink/iter/')
:Ns <- ITER.of(1 2 3 4)
:Mapped <- Ns.concat_map{(:N)
N.times
}
Mapped.each{(:M) stdout.print_line(M.repr) }
# => 0 0 1 0 1 2 0 1 2 3
6.64.1.5. Iter.filter($include?)¶
filterはIterの要素のうち$include?を満たすものを、iterとして戻す。要素の順序は変わらない。
事前条件
$include?は述語でなければならない。
例
:ITER.require_from('kink/iter/')
:Orig <- ITER.of(1 2 3 4 5 6 7 8 9)
:Evens <- Orig.filter{(:N) N % 2 == 0 }
Evens.each{(:N)
stdout.print_line(N.repr)
}
# Output:
# 2
# 4
# 6
# 8
6.64.1.6. Iter.count($counted?)¶
countは、Iterの要素のうち、$counted?を満たすものの数を戻す。
結果は整数のnum値である。
事前条件
$counted?は述語でなければならない。
例
:ITER.require_from('kink/iter/')
:Nums <- ITER.of(1 2 3 4 5 6 7 8 9)
:Count <- Nums.count{(:N) N % 2 == 0 }
stdout.print_line(Count.repr) # => 4
6.64.1.7. Iter.fold(Init $combine)¶
foldは、Initを種としてIterの要素を畳み込む。
Iterの要素がE1, E2, ,,, En_1, Enのとき、foldはcombine(combine(,,,combine(combine(Init E1) E2),,, En_1) En)を戻す。
Iterが空の場合、foldはInitを戻す。
事前条件
$combineはふたつの引数を取らなければならない。
例
:ITER.require_from('kink/iter/')
:Ns <- ITER.of(1 2 3 4 5)
stdout.print_line(Ns.fold(100){(:X :Y) X + Y }.repr) # => 115
6.64.1.8. Iter.reduce($combine ...[$empty_fallback])¶
reduceは、Iterの要素を相互に畳み込む。
Iterの要素がE1, E2, E3, ,,, En_1, Enのとき、reduceはcombine(combine(,,,combine(combine(E1 E2) E3),,, En_1) En)を戻す。
Iterの要素がEひとつのとき、reduceはEを戻す。
Iterが要素を持たず、$empty_fallbackが与えられているとき、reduceは$empty_fallbackを引数なしで末尾呼び出しする。
Iterが要素を持たず、$empty_fallbackが与えられていないとき、reduceは例外を投げる。
事前条件
$combineはふたつの引数を取らなければならない。
$empty_fallbackはサンクでなければならない。
例
:ITER.require_from('kink/iter/')
:Ns <- ITER.of(1 2 3 4 5)
stdout.print_line(Ns.reduce{(:X :Y) X + Y }.repr) # => 15
6.64.1.9. Iter.take_front(N)¶
take_frontは、Iterの最初のN個の要素をiterとして戻す。Iterの要素がN個より少ない場合、take_frontはIterの要素をすべて持つiterを戻す。
事前条件
Nは整数のnum値でなければならない。
例
:ITER.require_from('kink/iter/')
1.up.take_front(5).each{(:N)
stdout.print_line(N.repr)
}
# => 1 2 3 4 5
ITER.of(1 2 3).take_front(5).each{(:N)
stdout.print_line(N.repr)
}
# => 1 2 3
6.64.1.10. Iter.drop_front(N)¶
drop_frontは、Iterの要素から最初のN個を除いて、iterとして戻す。Iterの要素がN個より少ない場合、drop_frontは空のiterを戻す。
事前条件
Nは整数のnum値でなければならない。
例
:ITER.require_from('kink/iter/')
10.times.drop_front(5).each{(:N)
stdout.print_line(N.repr)
}
# => 5 6 7 8 9
10.times.drop_front(20).each{(:N)
stdout.print_line(N.repr)
}
# Output: nothing
6.64.1.11. Iter.take_while($include?)¶
take_whileは、すべての要素が$include?を満たすような、Iterの最長の先頭部分を、iterとして戻す。
事前条件
$include?は述語でなければならない。
例
:ITER.require_from('kink/iter/')
:Ns <- ITER.of(1000 500 250 125 62 31 15 7 3 1 0)
:Front <- Ns.take_while{(:N) N % 2 == 0 }
Front.each{(:N) stdout.print_line(N.repr) }
# => 1000 500 250
6.64.1.12. Iter.drop_while($exclude?)¶
drop_whileは、すべての要素が$exclude?を満たすような、Iterの最長の先頭部分を取り除き、残りをiterとして戻す。
事前条件
$exclude?は述語でなければならない。
例
:ITER.require_from('kink/iter/')
:Ns <- ITER.of(1000 500 250 125 62 31 15 7 3 1 0)
:Back <- Ns.drop_while{(:N) N % 2 == 0 }
Back.each{(:N) stdout.print_line(N.repr) }
# => 125 62 31 15 7 3 1 0
6.64.1.13. Iter.all?($match?)¶
all?は、Iterのすべての要素が$match?を満たすときにtrueを、そうでないときにfalseを戻す。
Iterが無限長のとき、all?は戻ることが保証されない。
事前条件
$match?は述語でなければならない。
例
:ITER.require_from('kink/iter/')
:Ns <- ITER.of(1 2 3 4 5)
stdout.print_line(Ns.all?{(:N) N < 10 }.repr) # => true
stdout.print_line(Ns.all?{(:N) N % 2 == 0 }.repr) # => false
6.64.1.14. Iter.any?(...[$match?={ true }])¶
any?は、Iterのひとつ以上の要素が$match?を満たすときにtrueを、そうでないときにfalseを戻す。
Iterが無限長のとき、any?は戻ることが保証されない。
$match?のデフォルト値は{ true }である。したがって、$match?が渡されない場合、any?はIterが空でないかどうかを戻す。
事前条件
$match?は述語でなければならない。
例
:ITER.require_from('kink/iter/')
:Ns <- ITER.of(1 2 3 4 5)
stdout.print_line(Ns.any?{(:N) N % 2 == 0 }.repr) # => true
stdout.print_line(Ns.any?{(:N) N > 10 }.repr) # => false
例
:ITER.require_from('kink/iter/')
stdout.print_line(ITER.of().any?.repr) # => false
stdout.print_line(ITER.of(1).any?.repr) # => true
stdout.print_line(ITER.of(1 2).any?.repr) # => true
6.64.1.15. Iter.concat¶
concatは、Iterの要素であるiterをつなげたiterを戻す。
事前条件
Iterは、iterを要素に持つiterでなければならない。
例
:ITER.require_from('kink/iter/')
:Nums <- ITER.of(1 2 3)
:Strs <- ITER.of('foo' 'bar')
:Bools <- ITER.of(true false)
ITER.of(Nums Strs Bools).concat.each{(:N)
stdout.print_line(N.repr)
}
# => 1 2 3 "foo" "bar" true false
6.64.1.16. Iter.unconcat(Chunk_size)¶
unconcatは、Iterを、長さがChunk_sizeであるベクタに分割して、そのベクタのiterを戻す。
Iterの長さが有限値のChunk_size * N + R, ただしNとRは非負の整数, であるとき、Iterの最後のR個の要素は捨てられる。
事前条件
Chunk_sizeは正の整数でなければならない。
例
:ITER.require_from('kink/iter/')
:Ns <- ITER.of(1 2 3 4 5 6 7)
:Chunks <- Ns.unconcat(2)
Chunks.each{(:Chunk)
stdout.print_line(Chunk.repr)
}
# Output:
# [1 2]
# [3 4]
# [5 6]
6.64.1.17. Iter.cycle¶
cycleはIterの要素を無限に繰り返したiterを戻す。
Iterが空の場合、結果のiterも空である。
例
:ITER.require_from('kink/iter/')
3.times.cycle.take_front(10).each{(:N)
stdout.print_line(N.repr)
}
# => 0 1 2 0 1 2 0 1 2 0
ITER.of().cycle.each{(:N)
stdout.print_line(N.repr)
}
# Output: nothing
6.64.1.18. Front + Back¶
+演算子、つまりop_addメソッドは、ふたつのiterであるFrontとBackを、ひとつのiterにつなげる。
事前条件
FrontとBackはiter値でなければならない。
例
:Iter <- 1.up.take_front(3) + 11.up.take_front(3)
Iter.each{(:N)
stdout.print_line(N.repr)
}
# => 1 2 3 11 12 13
6.64.2. ITER.new($ifun)¶
newは$ifunをラップするiterを戻す。
事前条件
$ifunはifunでなければならない。
例
:ITER.require_from('kink/iter/')
:make_vec_ifun <- {(:Vec)
{(:proc :fin)
if(Vec.any?
{ :Head = Vec.get(0)
:tail = make_vec_ifun(Vec.drop_front(1))
proc(Head $tail)
}
{ fin }
)
}
}
:Iter <- ITER.new(make_vec_ifun(['foo' 'bar' 'baz']))
Iter.each{(:S)
stdout.print_line(S)
}
# Output:
# foo
# bar
# baz
6.64.3. ITER.is?(Val)¶
is?はValがiterであるかどうかを戻す。
6.64.4. ITER.of(...Elems)¶
ofはElemsの要素を含むiterを戻す。
例
:ITER.require_from('kink/iter/')
:Iter <- ITER.of('foo' 'bar' 'baz')
Iter.each{(:S)
stdout.print_line(S)
}
# Output:
# foo
# bar
# baz
6.64.5. ITER.zip(First_iter ...Other_iters)¶
zipは、N個のiterが渡された場合、最短のiterと同じ長さのiterを戻す。結果のiterの要素は、長さNのベクタであり、ベクタの要素は対応する位置の引数のiterの要素からななる。
たとえば、iter Xが要素X1, X2, X3, ,,, からなり、YがY1, Y2, Y3, ,,, からなり、ZがZ1, Z2, Z3, ,,,, からなるとき、zip(X Y Z)は[X1 Y1 Z1], [X2 Y2 Z2], [X3 Y3 Z3], ,,, を要素とするiterを戻す。
事前条件
Other_itersの要素はiterでなければならない。
例
:ITER.require_from('kink/iter/')
:Zipped <- ITER.zip(
ITER.of(1 2 3 4 5)
ITER.of('foo' 'bar' 'baz')
ITER.of(true false true)
)
Zipped.each{(:Triple)
stdout.print_line(Triple.repr)
}
# Output:
# [1 "foo" true]
# [2 "bar" false]
# [3 "baz" true]
6.64.6. ITER.lazy($make_iter)¶
lazyは、$make_iterが戻したiterに要素の生成を委譲するようなiterを戻す。
サンク$make_iterは、結果のiterの内容が必要となった際に呼ばれる。
事前条件
$make_iterはiterを戻すサンクでなければならない。
例
:ITER.require_from('kink/iter/')
:count_down <- {(:N)
if(N < 0
{ ITER.of() }
{ ITER.of(N) + ITER.lazy{ count_down(N - 1) } }
)
}
count_down(5).each{(:N)
stdout.print_line(N.repr)
}
# => 5 4 3 2 1 0
6.64.7. ITER.from_generator($generator)¶
from_generatorは、$generatorの中で算出された要素を含むiterを戻す。
$generatorは、引数ひとつの関数$yieldを引数に取らなければならない。$generatorの呼び出しの中で$yieldが引数とともに呼ばれると、その引数が結果のiterの要素になる。$generatorの呼び出しが終わると、そこがiterの末尾になる。
$generatorは、結果のiterの内容が必要になったときに呼び出される。$generatorの呼び出しは、$yieldが呼ばれたときに中断される。呼び出しは、後続するiterの内容が必要になったときに再開される。
例: 有限長のiterを作る
:ITER.require_from('kink/iter/')
:Iter <- ITER.from_generator{(:yield)
yield('foo')
yield('bar')
yield('baz')
}
Iter.each{(:Str)
stdout.print_line(Str)
}
# Output:
# foo
# bar
# baz
例: 無限長のiterを作る
:ITER.require_from('kink/iter/')
:Iter <- ITER.from_generator{(:yield)
:loop <- {(:N)
yield(N)
loop(N + 1)
}
loop(1)
}
Iter.take_front(5).each{(:N)
stdout.print_line(N.repr)
}
# Output:
# 1
# 2
# 3
# 4
# 5
6.64.8. ITER.from_each(Eacher)¶
from_eachは、Eacher.eachで列挙される値を要素とするiterを戻す。
eachの呼び出しは、iterの要素が評価されるごとに中断、再開される。
事前条件
Eacherはeach($consume)メソッドをサポートしなければならない。eachはEacherの要素を列挙するために呼ばれる。
例
:ITER.require_from('kink/iter/')
:Take_five <- ITER.from_each([1 2 3 4 5])
Take_five.each{(:N)
stdout.print_line(N.repr)
}
# => 1 2 3 4 5