> Haskell has a much more expressive type system than Elm, but still lags behind Typescript unless you turn on a truly gargantuan number of extensions.
IIUC: it's not a total order, Haskell (even '98) has things TypeScript doesn't[0], and TypeScript has things that Haskell (even with extensions) doesn't[1].
Yeah you're right it's not a total order. I was being fast and loose and conveying a subjective feeling.
RE row polymorphism, Typescript doesn't quite have what users of ML-like languages are asking for when they want row polymorphism (which is usually parametric polymorphism rather than subtyping). But it's close.
As for convenient... well I'd argue by the time you've got the whole cornucopia of GHC extensions at the top of your file nothing is quite convenient at that point.
> RE row polymorphism, Typescript doesn't quite have what users of ML-like languages are asking for when they want row polymorphism (which is usually parametric polymorphism rather than subtyping). But it's close.
How would you distinguish this from the following?
function foo<T>(x: T & {field: number}): T {
...
}
> As for convenient... well I'd argue by the time you've got the whole cornucopia of GHC extensions at the top of your file nothing is quite convenient at that point.
That was one part of my point. That said, I think the problems implied by language extensions are often exaggerated (probably not deliberately so, most of the time).
The other part of my point was that even with all the extensions you need, I've not found good row types in Haskell, although the particular failings vary by approach. Which isn't to say I can't get something that works well enough for my particular situation most of the time.
function foo<T>(x: T & {field: number}): T {
return x;
}
function bar<T>(x: T & {field: number}): T {
const x0 = foo(x);
// type error because x0 doesn't have field
// would compile fine with row types
const x1 = foo(x0);
return x1;
}
Yes it's true. I also sorely miss the lack of row types in Haskell (I miss them even in something like Idris where you can create them more easily, but it's still not great compared to first-class support).
EDIT: I may be being dumb. You could probably fix this by adding an intersection type again on the right-hand side. I think there was something else I was missing from TS, but I'll have to noodle on it a bit more.
But yeah, I agree that duplicating the intersection produces another interesting question.
In any case, "convenient approximation of row types" probably still applies to TS more than Haskell. And possibly also "more convenient row types", but that remains TBD.
IIUC: it's not a total order, Haskell (even '98) has things TypeScript doesn't[0], and TypeScript has things that Haskell (even with extensions) doesn't[1].
[0]: eg. higher-kinded types [1]: eg. (convenient) row polymorphism