I’m somewhat surprised that this is actually valid syntax, but yeah, it looks like you can use any “free” identifier in place of the underscore.
$ cs launch scala:2.13.8
scala> trait Monad[F[_]]
scala> :kind -v Monad
Monad's kind is X[F[A]]
(* -> *) -> *
This is a type constructor that takes type constructor(s): a higher-kinded type.
scala> trait MonadT[F[T]]
scala> :kind -v MonadT
MonadT's kind is X[F[A]]
(* -> *) -> *
This is a type constructor that takes type constructor(s): a higher-kinded type.
I’d stick to the underscore, though. I’d think it’s more idiomatic, and it’s just the point that this is never used/referenced anywhere, but only filled in with a more specific type reference, so why bother giving it a name?
Note that with a type class, you separate the Monad concept from the type “having” a Monad. A full instance of the underlying type should be passed into the Monad, there should be no notion of the nested type A
attached to the Monad type itself.
trait Monad[F[_]]:
def pure[A](a: A): F[A]
def flatMap[A, B](fa: F[A])(f: A => F[B]): F[B]