日本語 · English

segmentBy — interval-sequence windows (cut at markers)

Translated from the canonical Japanese page reference/segmentBy.md. The source_sha above records the source revision; a consistency check flags this page when the Japanese original changes.

Category: window (body-layer core) / Signature: segmentBy(m, edges:, empties:) : Stream -> Stream(interval) / name settled (spec §5.4)

Meaning

Takes an arbitrary stream m as markers and makes each half-open interval [mᵢ, mᵢ₊₁) between adjacent markers a window. Every window whose boundaries are given by a sequence of points — fiscal closes, lunar phases (a lunisolar calendar cut at new moons), weeks (cut at the wkst-labeled day) — stands on this.

Unlike the partition type, exhaustiveness is not guaranteed, so the two arguments that state the meaning of the gaps explicitly are mandatory declarations (I5; omission is a static error). This closes off, by syntax, the accident in which firings silently vanish on missing data (ADR-15’s “accidental empty”).

Arguments

Argument Value Meaning
m stream expression the markers (the intervals’ boundary points)
edges: drop / clip / error treatment of points before the first marker / after the last marker (discard / make a partial window / error)
empties: keep / drop / error treatment of zero-element windows between markers (keep as a legitimate empty / discard / error)
labels: list (literal / list binding name) or the cyclic form cycle list anchor: real-day (ADR-47, below) a parallel label list for the window sequence (ADR-39); reading is binding-name projection name(d). For the combination constraints see “Preconditions and tightening rules” below — it cannot combine with edges: clip, empties: drop, or label:
label: lambda (p => expr) a computed label per window (ADR-34; for index expressions and conditional computations that do not fit labels:)

Examples

Lunisolar months cut at new moons — take the first day (the new-moon day) of each month. Lunar New Year 2026-02-17 appears:

# 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)

With edges: drop, nothing past the last marker 4/17 becomes a window (no silent continuation at the data’s edge).

labels: — a parallel label list for the window sequence (ADR-39)

Binds a data label sequence to the window sequence. Reading is binding-name projectionname(d) returns the label of the window that point d belongs to (defining equation name(d) ≡ labels[window-sequence ordinal]; in the window-sequence ordinal, the window starting at the first marker within the effective coverage is 0). A same-length check runs at evaluation: list length == window count (the window count is coverage-based = the marker count, independent of the evaluation range and the materialization range) — forgetting to update markers and labels as a pair breaks loudly as a static error (the vessel for 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)

Preconditions and tightening rules (all static errors; ADR-39 decision 4): it cannot combine with edges: clip (pseudo-windows shift the ordinals); it cannot combine with empties: drop (removing empty windows compacts the ordinals); it cannot coexist with a label: lambda (doubling the label source); it does not attach to rule markers (infinite sequences of the week class — periodic labels go to cycle, computed numbers to ordinalIn or label:); composite markers (t1 | t2) split the effective coverage so the window count is not determined — fix it first with a binding-postfix coverage claim (covering:). The reading port for an empty window’s label (empties: keep) is interval membership — any point within the window interval, in practice the marker point itself (the form in which an absent period’s number still stands). For several parallel sequences (numbers and names) the canonical form is separate window bindings over the same markers (the check bites twice; ../../stdlib/kyureki.md (Japanese) §1).

labels: cycle — a periodic label for the window sequence (ADR-47)

The shape “window sequence = the calendar’s unit, label = a fixed period” (the twelve branches of sekki-cut months, the monthly nine stars, the moon’s twelve signs) is written with the cyclic form labels: cycle list anchor: real-day. The semantics are identical to cycle on a window binding — “the window containing the anchor carries the first label” (list[(window-sequence ordinal − anchor window's ordinal) mod N]; negatives normalized by the modulus). No same-length check is imposed — as the covering grows over multiple years and markers increase, the anchor stays and the expression does not change by a single character (compatibility with external supply 〈ADR-46〉 is the aim of this form).

# 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)

The parenthesized named-arg segmentBy(m, edges:, empties:, label: (p => expr)) attaches a computed label to each window (p = the window’s first point; lazy evaluation at projection time). When merely pasting a data column, labels: is canonical (ADR-39, ADR-30 revised); label: is for computations involving index expressions and conditions (../../stdlib/kyureki.md (Japanese) §7 (5)).

Pitfalls

within · snapTo (granularity-matching the markers) · cycle (periodic labels) · table literals (bringing marker data in) · ADR-07/08/15 · I5.