This is more of a note-to-self than an informative post. Justin Le used the Data.Interval library a few times in his Advent of Code solutions, and intervals have come up previously. As the library is new to me, this is a note to remind me to use it in future!
I'm re-doing Advent of Code 2025 day 5 using this library. See that post for a description of the problem and my solution.
The Data.IntervalSet type does what I need: it stores a bunch of intervals, combining them as needed when they overlap. That means I can read the input file into a single IntervalSet and a list of points.
rangesP = IVS.fromList <$> rangeP `sepBy` endOfLine
rangeP = rangify <$> decimal <* "-" <*> decimal
where rangify l u = Finite l I.<=..<= Finite uThat makes solving the puzzle nearly trivial. Part 1 is "how many points are members of the interval set?":
part1 :: Ranges -> [Ingredient] -> Int
part1 ranges ingredients = length $ filter (`IVS.member` ranges) ingredientsPart 2 is "what's the widths of all the intervals?":
part2 :: Ranges -> Int
part2 = sum . fmap ((+1) . I.width) . IVS.toListCode
You can get the code from Codeberg.