Open 0xd34df00d opened 2 years ago
While I like this idea, we've decided against doing something like that a while ago for two reasons:
That being said, and with pirouette becoming more and more domain specific (i.e., the PR about the execution semantics independent symbolic evaluation failing to deliver), I can see how it will help solidify the codebase and help catching refactoring mistakes.
Personally, I'm always all-in for some type-fu! :muscle:
I like the fact that the type system helps us in applying the right transformations and I think that's relevant when transformation assume another one was previously done (for instance, assuming the terms will be in prenex form).
In terms of this attempt, it's very interesting, but I am wondering whether we can do better or not, because it seems to me that the type checker here does not enforce needed transformation to be called, but rather it gives in the type of the resulting transformation whether or not some additional constraints should be satisfied, that is when the first parameter of Xform
is non-empty.
Could we somehow enforce it ?
To answer this question, I think we should look at :
Is there anything we can learn from these to improve this solution?
Looks harmless enough if we are not storing transformations inside lists or collections where the type indices would make things tricky. @0xd34df00d made a good job at coming with a simple scheme.
But I'm still unconvinced that this is worth the trouble. When maintaining code I would expect to concern myself more with the reason of a dependency between transformations than with potentially missing a dependency when preparing a pipeline.
I'd be happy to drop this as well, so up to you folks as I'm obviously biased towards some type-level fun.
For the record, regarding @mmontin's question, the idea is that the type of the function that runs the pipeline is explicitly monomorphic, along the lines of
xform :: Xform '[] provides a -> a -> a
xform (Xform f) = f
Then, if you try to run something that has unsatisfied dependencies, GHC will complain along the lines of:
• Couldn't match type: '[Prenex]
with: '[]
We've discussed ways to ensure that all other transformations that a given one depends upon do indeed run before the given one. Preferably, at type level, so that the type also serves as a documentation.
I've been hacking a little bit on this today, and this is a proof-of-concept that I've come up with:
I'll see how well it integrates with the rest of pirouette tomorrow.