-
-
Notifications
You must be signed in to change notification settings - Fork 502
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
HKT abstraction no more typecheck with latest typescript dev version. #244
Comments
@sledorze Yeah, the build is broken if |
In case anyone is curious and want to help, there's a The best solution I found so far is declaring the typeclass members as bivariant. This is because I need to persuade the compiler that, for example, |
@gcanti there's a lot of modifications, I've tried yet to understand how the last version of typescript detects variance. |
Sure. This is a miniature of fp-ts export interface HKT<URI, A> {
_URI: URI
_A: A
}
export interface Functor<F> {
readonly URI: F
map: <A, B>(f: (a: A) => B, fa: HKT<F, A>) => HKT<F, B>
}
type Option<A> = Some<A> | None<A>
const URI = 'Option'
type URI = typeof URI
class None<A> {
_A: A
_URI: URI
_tag = 'None'
}
class Some<A> {
_A: A
_URI: URI
_tag = 'Some'
}
declare const map: <A, B>(f: (a: A) => B, fa: Option<A>) => Option<B>
const functor: Functor<URI> = { URI, map }
// ^ error: Type 'HKT<"Option", A>' is not assignable to type 'Option<A>' TypeScript 2.6 with
This is due to map: <A, B>(f: (a: A) => B, fa: HKT<F, A>) => HKT<F, B> Now by just changing the Functor definition to export interface Functor<F> {
readonly URI: F
- map: <A, B>(f: (a: A) => B, fa: HKT<F, A>) => HKT<F, B>
+ map<A, B>(f: (a: A) => B, fa: HKT<F, A>): HKT<F, B>
} we can make
|
Relying on declaration type (method or function) is quite a crutch but I hope if variance assertions ( |
@raveclassic not sure if it will make any difference, they are just assertions and we still must persuade the compiler that |
I think (I may be wrong) the problem is in additional fields on const a: Option<number | undefined> = some(undefined);
const double = (n: number): number => n * 2;
a.map(double); //no error because of bivariance If we are able to do smth like the following, then all the problems go away: interface Functor<out F> {
map<in A, out A2 extends A, out B>(f: (a: A) => B, fa: HKT<F, A2>): HKT<F, B>
} Correct me if I'm wrong, all this type theory is pretty new for me. |
Honestly I don't know, It's hard to say without an actual implementation to play with, we'll see. In the meantime I would like to find at least one solution to the current problem: the build is broken. Currently we are already paying for bivariance (thanks for the example above) so, even if I'm not completely happy with my solution, is not worse than what we get today. Anyone with a better idea? |
It's strage... I checked latest fp-ts@next branch and callback args are checked correctly! const a: Array<number | undefined> = [undefined]
const double = (n: number): number => n * 2
a.map(double) //error! hooray
const o: Option<number | undefined> = some(undefined)
o.map(double) //error! hooray
// Argument of type '(n: number) => number' is not assignable to parameter of type '(a: number | undefined) => number'.
// Types of parameters 'n' and 'a' are incompatible.
// Type 'number | undefined' is not assignable to type 'number'.
// Type 'undefined' is not assignable to type 'number'. Everything seems to be fine :) |
Maybe a bivariance annotation constraint would help.. |
@raveclassic Nice. The static version too import { Option, some, option } from 'fp-ts/lib/Option'
const o: Option<number | undefined> = some(undefined)
const double = (n: number): number => n * 2
const y = option.map(double, o) // error |
So, summing up, changing declaration to "method style" seems to solve both problems. We could even include the fix in |
breaking changes so far
and some methods here and there |
Ahh, looks like all "static" methods accepting a HKT instance (as a last argument) should be uncurried because if they return a function then its argument is checked contravariantly. Makes sense. |
@raveclassic yes that's what I've also seen so far. |
Some stats (checked against the current
I released a |
@gcanti unfortunately this leads to that kind of issues as I now have several version of fp-ts (though others libs - any idea how to workaround that?): Type 'Left<ValidationError[], B>' is not assignable to type 'Left<ValidationError[], B>'. Two different types with this name exist, but they are unrelated. |
@sledorze Which ones? We could install them from github. For a quick and dirty test I'm just manually removing the duplicates. |
@gcanti mainly io-ts not sure about monocle-ts or newtype-ts |
@sledorze if you run |
@gcanti only problem for me is missing |
@sledorze Great, thanks for the feedback |
New version: |
@sledorze |
@gcanti sorry for the delay, yes |
Just published
Let me know if
|
@gcanti ok big thanks! Will check in the 'next' days |
@gcanti the transition was painless, I've fully update our whole code base :) |
Official next version released, thank you all for your help, everybody. |
Try
Using latest typescript version (next) after 2.6.0-dev.20171006
(fp-ts is 0.5.2)
it may be related to that recent improvement:
microsoft/TypeScript@884c72e
The text was updated successfully, but these errors were encountered: