Newtypes are a lot of boilerplate and often feel like the wrong abstraction to use. Idris has a concept called named instances which has been proposed for inclusion in Haskell that avoid arbitrary wrapping and unwrapping. Functions which are generic over some constrained type can be passed a named instance instead of defaulting to the canonical one.
ML functors, while much more verbose than typeclasses/traits for the average usecase, have never had this problem of only one way of viewing a type/module as satisfying some constraint/signature because every usage is named in the first place, leading to very intuitive, highly polymoprhic abstractions. You also cannot mix up your “different views” because both generative and applicative functors are type incompatible for different arguments. Thus, something like BTreeSet<i32> is incompatible with BTreeSet<i32 as IntReverseOrd>. (With ML functors, you might even be able to write something like BTreeSet<i32 as Reverse(Int)>, where Reverse is a functor which takes an Ord impl and produces a new, anonymous, reversed Ord impl).
I am not going to float any syntax ideas besides Identifier<Type as NamedInstance> and fun_identifier::<Type as NamedInstance>, and that obviously doesn’t answer the question of multiple trait bounds or input parameters for traits. In any case, I think with trait impl specialization coming, it would be good to investigate other, useful ways of increasing expressiveness and being friendly to users.
Has this had an RFC in the past? I couldn’t find anything.