While studying functional programming and exploring the concept of continuations, I became acquainted with the types (monad transformers) Codensity and ContT. They look similar, but it is still not clear how they relate. It seems like Codensity is more primary than ContT, doesn't it?
In Scala 3, such types can be written like this:
type Codensity = [F[_]] =>> [A] =>> [B] => (A => F[B]) => F[B]
type ContT = [F[_]] =>> [A, B] =>> (A => F[B]) => F[B]
How to infer the type of ContT when Codensity is specified (assuming we don’t know in advance what ContT is)? And on what grounds? Or some other inference of one type based on another?
You're right. The difference is not only in currying (polymorphic function vs. type lambda).
How would you answer your question in easier situation?
"How to infer the type of
XwhenYis specified?"Xis a type depending onA.Yis a type whose term (value) depends onA.XisList.Yis inhabited for example withNil[A](if we consider invariant list i.e.instead of
).
Relation between two types is the following. For a value of type
Y, this value applied toAbelongs to the typeXapplied toA.Is type constructor
Listmore primary than polymorphic functionNil[A]?Here in order to get a proper type (i.e. a type of kind
*), forContTwe have to fixF,A,B, forCodensitywe have to fixF,A.[B] =>> (A => F[B]) => F[B]is a type depending onB.[B] => (A => F[B]) => F[B]is a type whose term depends onB.Relation between two types is the following. For a value of type
Codensity[F][A], this value applied toBbelongs to the typeContT[F][A, B]