-
Notifications
You must be signed in to change notification settings - Fork 50
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Existential (phantom ?) type parameters on constructors #26
Comments
Yes, this is something that I wanted to add to the roadmap (and also planned by adt4j in sviperll/adt4j#15 and sviperll/adt4j#38). @Data(flavour = Flavour.FJ)
abstract class Stream<A> {
static class Step<A, S> {/*...*/}
interface Cases<R, A> {
<S> R Stream(F<S, Step<A, S>> stepper, S init);
}
abstract <R> R match(Cases<R, A> cases);
} should totally be doable. The main pain point is that I cannot use lambdas anymore to instantiate |
Argh ! This is unfortunate indeed. Would it affect the user interface ? |
Well, it will impact pattern matching: you will need to either use method reference or traditional instantiation of a (anonymous) class |
Oh noes... And my first proposition ? (phantom type on the Cases interface ?) |
I think in the first proposition you would be forced to use |
Even by threading the type all along ? Streams.<A, S>cases()
.Stream(...) or with the myStream.<A, S>match(...) (assuming |
mmm... where does |
Yeah, I was considering things on the user side only but I've not (yet) looked at your code and the way it generates its (immensely beneficial ) mess... |
Indeed, this public abstract class Stream<A> {
private Stream() {}
protected abstract <S, R> R match(F3<Unlifted<S>, F<S, Step<A, S>>, S, R> f);
private static final class Impl<A, S> extends Stream<A> {
final Unlifted<S> us;
final F<S, Step<A, S>> stepper;
final S init;
private Impl(Unlifted<S> us, F<S, Step<A, S>> stepper, S init) {
this.us = us;
this.stepper = stepper;
this.init = init;
}
@Override
protected <S, R> R match(F3<Unlifted<S>, F<S, Step<A, S>>, S, R> f) {
return f.f(us, stepper, init);
}
}
} obviously doesn't compile... |
@gneuvill what I meant is that even without speaking of the code-generation part, the first proposition is impossible to implement: abstract class Stream<A> {
interface Cases<R, S, A> {
R Stream(F<S, Step<A, S>> stepper, S init);
}
abstract <R, S> R match(Cases<S, R, A> cases);
static <S1, A> Stream<A> Stream(F<S1, Step<A, S1>> stepper, S1 init) {
return new Stream<A>() {
@Override <S2, R> R match(Cases<S2, R, A> cases) {
F<S2,Step<A,S2>> _stepper = ???;
S2 _init = ???;
return cases.Stream(_stepper, _init);
}
};
}
} |
😄 |
Je comprends vite mais faut m'expliquer longtemps... |
I know this is an old issue, but I've seen a solution to this in purescript.
is really ment to be
_exists_ because there is only one type for You can define a helper class Or you can also mimic an That is: |
This is my first time trying derive4j. I believe the following is one possible solution: https://gist.github.com/clinuxrulz/0a56108f31bafa1452b7b38eba198285 Edit: Also if you want to define the Edit: Example: Creating a
Little bit messy. |
Hi @clinuxrulz, Here is the reasoning I followed to transcribe the as you noted, See https://gist.github.com/gneuvill/ec3f7c434549a19eefe7697e9549a849 for the complete example. What I like in this encoding is that it makes use of the 'true' java existentials in a type safe way ; however the drawbacks of this approach is that you must use helper methods to 'capture' the wildcard ( |
@gneuvill I like it, and I did not know Java could do that. I'll remember that trick. |
Hey, me again,
the following haskell idiom seems currently not expressible using derive4j :
Would it be possible to allow that kind of construct :
or better
What do you think ?
The text was updated successfully, but these errors were encountered: