日本語 · English

segmentBy — 区間列型窓(マーカーで切る)

分類: 窓(本体層 core) / シグネチャ: segmentBy(m, edges:, empties:) : Stream -> Stream(interval) / 名は確定(spec §5.4)

意味

任意のストリーム mマーカーとし、隣り合うマーカーの半開区間 [mᵢ, mᵢ₊₁) を窓とする。 決算期・月相(朔で切る太陰太陽暦)・週(wkst ラベル日で切る)など、「点の列が境界を与える」窓は すべてこれで立つ。

パーティション型と違い網羅は保証されないので、隙間の意味を明示する二つの引数が宣言必須 (I5・省略は静的エラー)。データ欠損で発報が静かに消える事故(ADR-15「事故の空」)を構文で防ぐ。

引数

引数 意味
m ストリーム式 マーカー(区間の境界点)
edges: drop / clip / error 最初のマーカー前・最後のマーカー後の点の扱い(捨てる/部分窓を作る/エラー)
empties: keep / drop / error マーカー間の要素ゼロ窓の扱い(正当な空として保持/捨てる/エラー)
labels: リスト(リテラル/リスト束縛名)または周期形 cycle リスト anchor: 実日(ADR-47・後述) 窓列への並行ラベル列(ADR-39)。読みは束縛名射影 束縛名(d)。組合せの締めは「前提条件と締め」(後述)——edges: clipempties: droplabel: とは組めない
label: ラムダ (p => 式) 窓の計算ラベル(ADR-34。labels: に乗らない添字式・条件つき計算用)

朔(新月)で切る旧暦月——各月の第 1 日(朔日)を採る。旧正月 2026-02-17 が現れる:

# eval: 2026-01-01..2026-05-01
@JP
newMoons = [2026-01-19T04:52, 2026-02-17T21:01, 2026-03-19T10:23, 2026-04-17T20:52]
lunarStart = newMoons |> snapTo(day)
everyDay |> segmentBy(lunarStart, edges: drop, empties: drop) |> first
#=> 2026-01-19 2026-02-17 2026-03-19
#~> 範囲外 2026-01-01..2026-01-19(newMoons covering 2026-01-19T04:52..2026-04-17T20:52)
#~> 範囲外 2026-04-17..2026-05-01(newMoons covering 2026-01-19T04:52..2026-04-17T20:52)

edges: drop なので最後のマーカー 4/17 以降は窓にならない(データの端で黙って続けない)。

labels:——窓列への並行ラベル列(ADR-39)

データのラベル列を窓列に結ぶ。読みは束縛名射影——束縛名(d) が点 d の属する窓のラベルを返す (名前(d) ≡ labels[窓列序数]・窓列序数は実効被覆域内の先頭マーカー起点の窓が 0)。同長性検査が 評価時に走る: リスト長 == 窓数(窓数は覆域基準=マーカー数。評価範囲・実体化範囲に依存しない)—— マーカーとラベルの対更新忘れが静的エラーで割れる(F62 の器):

# eval: 2026-01-01..2026-07-01
@JP
newMoons = [2026-01-19T04:52, 2026-02-17T21:01, 2026-03-19T10:23, 2026-04-17T20:52]
  covering: 2026-01-19..2026-04-30
lunarMonth = everyDay |> segmentBy((newMoons |> snapTo(day)), edges: drop, empties: error,
                                   labels: [12, 1, 2, 3])
lunarMonth |> first |> filter(d => lunarMonth(d) == 1)
#=> 2026-02-17
#~> 範囲外 2026-01-01..2026-01-19(newMoons covering 2026-01-19..2026-04-30)
#~> 範囲外 2026-05-01..2026-07-01(newMoons covering 2026-01-19..2026-04-30)

前提条件と締め(すべて静的エラー・ADR-39 判断 4): edges: clip とは組めない(擬似窓が序数を ずらす)・empties: drop とは組めない(空窓の除去が序数を詰める)・label: ラムダと同居できない (ラベル源の二重化)・規則マーカー(week 型の無限列)には付かない(周期ラベルは cycle・計算番号は ordinalInlabel:)・合成マーカー(t1 | t2)は 実効被覆域が割れて窓数が確定しないので、束縛後置の被覆主張(covering:)で確定してから。 空窓(empties: keep)のラベルの読み口は区間所属——窓区間内の任意の点、実用上はマーカー点 そのものから読める(欠ティティの番号が立つ形)。複数の並行列(番号と名前)は同じマーカーで 別の窓束縛を立てるのが正準(検査が二重に効く。../stdlib/kyureki.md §1)。

labels: cycle——窓列への周期ラベル(ADR-47)

「窓列=暦の単位・ラベル=固定周期」の形(節切り月の十二支・月家九星・月星座の 12 宮)は 周期形 labels: cycle リスト anchor: 実日 で書く。意味論は窓束縛への cycle と 同一——「anchor の属する窓が先頭ラベル」(list[(窓列序数 − anchor 窓の序数) mod N]・負も 法で正規化)。同長性検査は課さない——covering が複数年に伸びてマーカーが増えても、anchor は そのままで式は一字も変わらない(external 供給〈ADR-46〉との相性がこの形の狙い)。

# eval: 2026-02-03..2026-02-06
@JP
setsu = [2026-01-05, 2026-02-04, 2026-03-05, 2026-04-04] covering: 2026-01-05..2026-04-04
sekkiMonth = everyDay |> segmentBy(setsu, edges: drop, empties: error,
                                   labels: cycle [寅, 卯, 辰, 巳, 午, 未, 申, 酉, 戌, 亥, 子, 丑]
                                   anchor: 2026-02-04)
everyDay |> filter(d => sekkiMonth(d) == 寅)
#=> 2026-02-04 2026-02-05

label:(ADR-34)

括弧内の named-arg segmentBy(m, edges:, empties:, label: (p => 式)) で各窓に計算ラベルを貼れる (p=窓の先頭点・射影時の遅延評価)。データ列を貼るだけなら labels: が正準(ADR-39・ADR-30 改訂)で、 label: は添字式・条件を含む計算用(../stdlib/kyureki.md §7 (5))。

落とし穴

関連

withinsnapTo(マーカーの粒度合わせ)・cycle(周期ラベル)・ テーブルリテラル(マーカーのデータ持ち込み)・ADR-07/08/15・I5。