Coding 2021-07-05
I took things easy again today, so the main progress I made was in realizing that the idiom I'm trying to work with requires using Iterators instead of providing a function for iteration. The point of this is to make it so that if I "reuse" a dataclass instance, its Actions and Targets only get added to the Registry once.
I don't know if this is the right approach, but I have a gut feeling that I don't want to lean on the type system for really fine-grained stuff, and instead have a few simple types that relate via operations like "compose" and "fan-in". So, like, maybe the type would be as simple as the Iterator and a mapping from strings to sets of data.
Something like...
# It's a little weird that it's frozen with mutable state, but meh.
@attr.dataclass(frozen=True)
class State:
changes: Iterator[Change]
data: PMap[str, PSet[Union[str, Path]]]
def combine(*args: State) -> State:
changes = (c for arg in args for c in arg.changes)
data = {}
for arg in args:
for k, v in arg.data.items():
data.setdefault(k, set()).update(v)
return State(changes, pmap({k: pset(v) for k, v in data.items()}))
And then you just have the new state as the last argument. This code is totally untested and unpolished, but I think it gets the basic idea across.
I'm doing basic tests on it right now, and I'll try actually using it later, but it's late now and I want to get to bed.
Good night.