In Scala there is no rank-2 polymorphism. It means methods (and moreover functions which are not even polymorphic at all) can't except arguments with universal quantifiers (all universal quantifications should be done on method level). So we can have methods like
def f[A, B[_], C[_[_]]](x: A, y: B[A], z: C[B]) = ???
but not like (pseudocode)
def f(x: [A] A, y: [A1, B[_]] B[A1], z: [B1[_], C[_[_]]] C[B1]) = ???
Also this means we can't substitute type constructor to the place where a specific type is expected (really, a type constructor B[_]
can be considered as [A] B[A]
, C[_[_]]]
as [B[_]] C[B]
or [[A] B[A]] C[B]
).
But to make types and type constructors look more uniformly you can wrap a type constructor with a trait type. For example you can look at the following encoding (it's surely wordy, you have to wrap-unwrap types all the time):
trait Type
trait ConcreteType extends Type {
type T
}
trait TypeConstructor[U] extends Type {
type l[X <: U] <: ConcreteType
}
type Type0 = ConcreteType
type Type1 = TypeConstructor[Type0]
type Type2 = TypeConstructor[Type1]
type Type3 = TypeConstructor[Type2]
// type A = Int
type A = Type0 {type T = Int}
// type B[X] = List[X]
type B = Type1 {
type l[X <: Type0] = Type0 {type T = List[X#T]}
}
trait Functor[F[_]]
// type C[F[_]] = Functor[F]
type C = Type2 {
type l[F <: Type1] = Type0 {
type T = Functor[
({
type ll[X] = (F#l[Type0 {type T = X}])#T
})#ll
]
}
}
trait Generic[FF[_[_]]] // like shapeless.Generic1, shapeless.IsHCons1, shapeless.IsCCons1
// Generic1[F[_], FR[_[_]]], IsHCons1[L[_], FH[_[_]], FT[_[_]]], IsCCons1[L[_], FH[_[_]], FT[_[_]]]
// Generic1[F, Functor], IsHCons1[L, Monad, Monad], IsCCons1[L, Applicative, Applicative]
// type D[FF[_[_]]] = Generic[FF]
type D = Type3 {
type l[FF <: Type2] = Type0 {
type T = Generic[
({
type ll[F[_]] = (
FF#l[Type1 {
type l[X <: Type0] = Type0 {type T = F[X#T]}
}]
)#T
})#ll
]
}
}
import shapeless.{::, HNil}
type lst = A :: B :: C :: D :: HNil
Some links:
https://wiki.haskell.org/Rank-N_types
https://en.wikibooks.org/wiki/Haskell/Polymorphism#Higher_rank_types
https://apocalisp.wordpress.com/2010/07/02/higher-rank-polymorphism-in-scala/