2 ms·
> That's not the same however, because the modules language is a lot more constrained than the term language. You don't need to tell me. That's obvious to anyo
by catnaroek 11y ago
> That's not the same however, because the modules language is a lot more constrained than the term language.
You don't need to tell me. That's obvious to anyone who has programmed in ML. But Haskell's type class language is similarly a lot more constrained than its term language. It's basically a pure (in particular, cut-free) compile-time Prolog, with some restrictions to guarantee that no query will return more than one result.
> See the first paragraph the second page of https://www.mpi-sws.org/~rossberg/1ml/1ml-extended.pdf https://www.mpi-sws.org/~rossberg/1ml/1ml-extended.pdf.
Rest assured, I've read the paper - not today, but several months ago. I'm quite familiar with the ML module literature. Check my post history:
https://news.ycombinator.com/item?id=10856201 https://news.ycombinator.com/item?id=10856201
https://news.ycombinator.com/item?id=11131265 https://news.ycombinator.com/item?id=11131265
But, since you're arguing that the combination of type classes and higher-kinded types can do something that ML modules can't, I'm providing evidence for the opposite: everything that can be done with type classes and higher-kinded types can be done with modules.
(0) You can't compute new modules at runtime, but you also can't define new type class instances at runtime.
(1) An ML module can have both transparent and abstract type components, controlled by the programmer. A type class always has abstract type components at definition time, and transparent type components at instantiation time. Modules are more expressive than type classes.
(2) The signature of an ML module is structural, and you can, after the fact, selectively forget part of a module's contents. Type classes don't let you do this. Try making `Monoid` a subclass of `Semigroup` without recompiling any existing code. Again, modules are more expressive than type classes.
As for higher kinds, at least with OCaml's higher-order applicative functors, you can encode arbitrary higher-kinded type constructors. And most of the higher-kinded constructors that actually arise in practice can be encoded even with Standard ML's first-order functors.
- Ericson2314 11y ago> Rest assured, I've read the paper Don't worry, I quote the paper not because I doubt your ML experience, but to make sure that I don't mess up the peculiars of the situation. I've spent more time thinking about the design of SML/OCaml than using them, and wouldn't want to undermine my argument with a mis-remembered surface syntax. My point with this arguments is not that "polymorphic instances" are as powerful as functors (they aren't!). Rather in this (and similar examples) it's higher-kinded types vs modules, no type classes involved. The Haskell equivalent is just a plane function, not a polymorphic instance, and there is things that can be done in the term language but not the module language. SML/OCaml with higher-kinded types would annihilate this argument, no type classes or implicits needed, but don't yet exist.
- catnaroek 11y ago> My point with this arguments is not that "polymorphic instances" are as powerful as functors (they aren't!). Rather in this (and similar examples) it's higher-kinded types vs modules, no type classes involved. This paper disagrees: http://www.cse.unsw.edu.au/~chak/papers/modules-classes.pdf http://www.cse.unsw.edu.au/~chak/papers/modules-classes.pdf . See below. > The Haskell equivalent is just a plane[sic] function, not a polymorphic instance, and there is things that can be done in the term language but not the module language. A plain function can't return fresh new types. A functor can. > SML/OCaml with higher-kinded types would annihilate this argument As I said above, OCaml's higher-order modules let you encode arbitrarily higher-kinded types. Even if OCaml didn't have parametric polymorphism in the core language, you can express it in the module language with applicative functors (although the result would be a lot more verbose). If you don't believe me, give me an arbitrary higher-kinded type, and I'll tell you how to encode it in OCaml.
- Ericson2314 11y agoI don't have time to read the paper for a few days, but I meant while functors can do things functions cannot do, functions can do things functors cannot do too.
- catnaroek 11y agoAnd records can do things functions can't do. And vice versa. That alone doesn't mean records in one language are the counterpart of functions in another.
- Ericson2314 11y agoHow is that relevant? I'm claiming that their exists functions in Haskell that cannot be encoded either as functor or functions in ML. (If you want, I'll try to come up with an example, but my guess would be some funny polymorphic recursion + higher-kinded types)