Open dima-starosud opened 1 year ago
OK. Found the solution:
fn a_5<T>(a: A<T>) -> A<()> {
let a = frunk::into_labelled_generic(a);
frunk::from_labelled_generic(hlist![field![_, PhantomData::<()>], ...a].sculpt().0)
}
But is that the best way to do this?
Thanks for putting up this question. To be honest, I don't consider this to be a trivial thing at all, so it's great that you figured it out. The final solution looks good, and I'm not sure I could come up with something better: building the toolkit is one thing, figuring out how to to "best" use it is something the community generally figures out better, so I'd recommend sending this to SO to see what smart ppl can figure out 😄
I'm actually quite amazed to see how much the compiler is actually able to "figure out" for you in your solution in that last line ... (placeholder field name type....sculpting...then into labelled generic). Since IME, the compiler optimises out all the intermediates states when run in release mode, my only thought is whether this going to cause you compile time woes if you have much more complex structs that you're planning to do this with. e.g. if need be (compiling takes long, or it can't figure things out), it could be worth trying to help it along with types..
fn a_5<T>(a: A<T>) -> A<()> {
use frunk::labelled::chars::*;
type ph = (p, h);
let a = frunk::into_labelled_generic(a);
frunk::from_labelled_generic(hlist![field![ph, PhantomData::<()>], ...a].sculpt().0)
}
Thank you! I appreciate the clarification.
There is an unstable feature type changing struct update syntax which should support this out of the box, and I thought that frunk
could have this as a kind of killer feature while std one is unstable.
That reminded me a quote by Alan Kay "Simple things should be simple, complex things should be possible.". And to me mapping a single field from T
to ()
doesn't seem to be a complex thing 🤔
Probably with overlapping instances, it could be more straightforward:
let a = frunk::into_generic(a);
let a = a.map(poly_fn![[T] |_: PhantomData<T>| PhantomData::<()>]);
frunk::from_generic(a)
And I think I saw some utility which does into/from for us, so the final could be:
with_generic(a, |a| a.map(poly_fn![|_: [T] PhantomData<T>| PhantomData::<()>]))
But I think you're right, there is a place for this in SO.
@dima-starosud gotcha. It might make sense to have this in example
or tests
so that it can be checked + documented ?
Sure 👍 would be great to have this in the example folder I think. I can make a PR if needed.
@lloydmeta Could you assign this to me?
Posted the question https://stackoverflow.com/questions/76612428/stable-analogues-of-type-changing-struct-update-syntax.
Will proceed with the ticket once get some good answers to it.
I am guessing SO is probably a better place to ask this, but my case is so trivial, that I would expect to see an example of it in README or docs.
There is a generic struct:
and I want to avoid boilerplate doing the following:
What would be the best way to do this with
frunk
?Also, it would be great to add an example to the docs.
I've tried these:
transmogrify doesn't work probably because types of
PhantomData<T>
andPhantomData<()>
are different;map
- need overlapping instances:pluck
- not sure why it doesn't work: