Modules can be seen as a collection of types (abstract or otherwise) and functions acting upon those types. Very prosaically, this can just be a type parameterized dictionary (or vtable if that floats your boat).
Haskell's "constrained" types look like this
c => a
where the type `a` requires access to the details of a constraint `c`. It turns out that constraints are merely type parameterized dictionaries of functions acting upon those types. We could reify them into concrete data types if we liked and then replace the fat arrow
(Dict of c) -> a
and get something functionally equivalent.
Now, instead of doing that Haskell has the typeclass mechanism which allows the compiler to automatically generate and pass needed constraints based on a prolog-like logic that executes at compile time. This can be convenient but restricts the flexibility of these dictionaries.
ML modules can do some of the very same things but require the user to manually wire the proper module in at the right time instead of letting the compiler do it [0]. The benefit is that your modules are more modular and can support more sophistication.
[0] Caveat: this compiler automatic dictionary wiring will be enabled, in part, with OCaml's modular implicits which are coming down the pike soon.
Haskell's "constrained" types look like this
where the type `a` requires access to the details of a constraint `c`. It turns out that constraints are merely type parameterized dictionaries of functions acting upon those types. We could reify them into concrete data types if we liked and then replace the fat arrow and get something functionally equivalent.Now, instead of doing that Haskell has the typeclass mechanism which allows the compiler to automatically generate and pass needed constraints based on a prolog-like logic that executes at compile time. This can be convenient but restricts the flexibility of these dictionaries.
ML modules can do some of the very same things but require the user to manually wire the proper module in at the right time instead of letting the compiler do it [0]. The benefit is that your modules are more modular and can support more sophistication.
[0] Caveat: this compiler automatic dictionary wiring will be enabled, in part, with OCaml's modular implicits which are coming down the pike soon.