It seems there's a subtle difference between type decleration for named function() syntax vs anonynous function syntax:
type F<X, Y> = (x: X) => Y
// works:
function apply<X, Y>(f: F<X, Y>, x: X) : Y {
return f(x)
}
// works:
const apply0 : <X, Y>(f: F, x: X) => Y = (f, x) => f(x)
// doesn't work
const apply1 : <X, Y>(f: F<X, Y>, x: X) => Y = (f, x) => f(x)
Flow console snippet
I need to remove generic type annotation from any reference to type F<X, Y> in the arguments of anonymous apply function for type checker to work.
This is counterintuitive.
[Edit:] But it seems that Flow is able to type check apply1 calls even though it fails to type check apply1 itself:
apply1(x => x * 2, 'a') // error: ^ string. This type is incompatible with
apply1(x => x * 2, 1) // works
More generally:
// works:
type Apply<X, Y> = <X, Y>(f: F, x: X) => Y
const apply : Apply = (f, x) => f(x)
// doesn't work:
type Apply1<X, Y> = <X, Y>(f: F<X, Y>, x: X) => Y
const apply1 : Apply1 = (f, x) => f(x)
Flow console snippet
I have to remove generic type annotation X, Y from the arguments of type alias Apply for Flow to type check it.
Is it the intended behavior or am I missing something?
const apply1 = <X, Y>(f: F<X, Y>, x: X): Y => f(x)
First, as @squint mentioned in a comment, F without type arguments implicitly means F<any, any>, which is why apply0 works in your example.
So why does your apply1 have an error? Well, it's due to the fact that Flow does not infer generics. so when you wrote
const apply1 : <X, Y>(f: F<X, Y>, x: X) => Y = (f, x) => f(x)
the right hand side of the assignment is
(f, x) => f(x)
and Flow can't infer that this arrow function is polymorphic. So you could just add type parameters to the RHS like this:
const apply1 : <X, Y>(f: F<X, Y>, x: X) => Y = <X, Y>(f: F<X, Y>, x: X): Y => f(x)
and that should fix the error. But at this point, the type annotation on the left hand side is no longer necessary. So you can simplify it to
const apply1 = <X, Y>(f: F<X, Y>, x: X): Y => f(x)
Avik Chaudhuri wrote a short explanation on a similar stack overflow question, which in turn links to a similar answer on GitHub
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With