'Erik Ernst' via Dart Misc
2018-10-13 13:51:32 UTC
X Function() Function<Y>() hkt<X>(X Function<Y>() func) => <Y>() => () => func<Y>();
List<T> makeList<T>() => <T>[];
void main() {
List<int> x = hkt(makeList)<int>()();
}
This abomination crashes CFE, and makes the Analyzer cry (sometimes it
crashes, other times it says List<Y> is not a List<int>)...
But honestly, my main question is "how does the language specification
handle this?"
An abomination indeed, but it's very good that you have brought out someList<T> makeList<T>() => <T>[];
void main() {
List<int> x = hkt(makeList)<int>()();
}
This abomination crashes CFE, and makes the Analyzer cry (sometimes it
crashes, other times it says List<Y> is not a List<int>)...
But honestly, my main question is "how does the language specification
handle this?"
bugs, please report <https://github.com/dart-lang/sdk/issues/new> them!
The language specification says that it is a compile-time error to call a
function like `hkt` with an actual argument whose type is not assignable to
the corresponding formal parameter type. For subtyping among generic
function types, we need to ensure that the two functions have the same
number of type arguments and the same bounds (not just subtype related in
some way, they must have the same type as bound for each parameter), and
then we lower to non-generic functions (where the type variables may occur
free, but are in the environment with their bounds assumed).
The type of `makeList` is `List<Y> Function<Y>()` (doing the
alpha-conversion now) and the parameter type is `X Function<Y>()`, so we
must now have assignability (subtyping one or the other way) among `List<Y>
Function()` and `X Function()`. But they are unrelated types, because the
environment doesn't give any relationships between `X` and any other type.
So all you get is a compile-time error (except that we need a couple of bug
fixes first).
But you can use implicit generic function instantiation on `makeList` to
turn it into a `List<int> Function()` (basically, this is a curried
application where `makeList` receives its type argument `int`), and this
will happen if you let `hkt` take a non-generic function and ensure that
the relevant type argument is available.
Because of the multiple function calls (and the fact that Dart has
subtyping) you won't get the type argument from inference, so you need to
pass it explicitly.
Here's the result:
X Function() Function() hkt<X>(X Function() func) => () => () =>
func();List<T> makeList<T>() => <T>[];
void main() {
List<int> x = hkt<List<int>>(makeList)()();
}
At this point, of course, you can eliminate one level of functions in the
typing and body of `hkt`, and remove one `()` in `main`, but this basically
makes `hkt` the identity function, in which case you might want to reduce
the whole thing to `List<int> x = makeList();` in `main`. ;-)
best regards,
--
Erik Ernst - Google Danmark ApS
Skt Petri Passage 5, 2 sal, 1165 KÞbenhavn K, Denmark
CVR no. 28866984
--
For more ways to connect visit https://www.dartlang.org/community
---
You received this message because you are subscribed to the Google Groups "Dart Misc" group.
To unsubscribe from this group and stop receiving emails from it, send an email to misc+***@dartlang.org.
To view this discussion on the web visit https://groups.google.com/a/dartlang.org/d/msgid/misc/CACDCfDQ0HWE0y_9gqXYDz0A%3DAO9_n5syQzkhR78v2_Lc6gSZTg%40mail.gmail.com.
For more ways to connect visit https://www.dartlang.org/community
---
You received this message because you are subscribed to the Google Groups "Dart Misc" group.
To unsubscribe from this group and stop receiving emails from it, send an email to misc+***@dartlang.org.
To view this discussion on the web visit https://groups.google.com/a/dartlang.org/d/msgid/misc/CACDCfDQ0HWE0y_9gqXYDz0A%3DAO9_n5syQzkhR78v2_Lc6gSZTg%40mail.gmail.com.