| >Um, aren't functional dependencies an add-on to multiparameter type classes? You're right, I meant "type families". > I defined two type instances that violate the principle of not doing evil: We're not doing abstract category theory; we're writing computer programs (well, I am). Have you ever run into a problem with type families in that capacity? >if two types are isomorphic, applying the same type constructor to them should yield isomorphic types. Agreed, but there's a difference between type functions and type constructors. TFs are (a limited form of) type functions. Value-level constructors admit lots of nice properties that value-level functions do not, and I see no reason to be uncomfortable with this being reflected at the type level. > What if I want to order them as Grey-coded numbers Use a newtype wrapper. Even if a language allowed ad-hoc instances, I would consider it messy practice to apply some weird non-intuitive ordering like this without specifically making a new type for it. > Creating `newtype` wrappers is easy at the type level, but using them is super cumbersome at the term level. And using ML-style modules is easy at the term level, but cumbersome at the type level. It's a tradeoff, and I suspect that newtypes are usually the cleaner/easier solution. > ML modules are plain System F-omega I hadn't seen the 1ML project. That's pretty cool. > It's type families, as done in Haskell, that violate parametricity! How so? I really don't understand your argument here, if you just take TFs to be a limited form of type function. |
I like being able to reason about my programs. For that to be a smooth process, the language has to be mathematically civilized.
> Agreed, but there's a difference between type functions and type constructors. TFs are (a limited form of) type functions.
By “type families”, I meant both data families and type families. Case-analyzing types is the problem, see below.
> And using ML-style modules is easy at the term level, but cumbersome at the type level.
Actually, ML-style modules are also more convenient at the type level too! If I want to make a type constructor parameterized by 15 type arguments, rather than a normal type constructor in the core language, I make a ML-style functor parameterized by a structure containing 15 abstract type members.
> How so? I really don't understand your argument here, if you just take TFs to be a limited form of type function.
“In programming language theory, parametricity is an abstract uniformity property enjoyed by parametrically polymorphic functions, which captures the intuition that all instances of a polymorphic function act the same way.”
https://en.wikipedia.org/wiki/Parametricity