trait Monad[F[_], A] { // higher-kinded type class
def flatMap[B](f: A => F[B]): F[B]
def map[B](f: A => B): F[B]
}
hi, in the code above, can I use Monad[F[T], A] to replace the Monad[F[_], A]? I tried in AMM, the compiler didn’t complain, and I think they are the same, but I am not sure.
hope anybody could explain a little.
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.
A quick experiment seems to show that they are the same; i.e. the inner identifier doesn’t refer to the outer one (the actual type), is just the syntax to specify the kind.
Which also means that they probably won’t do what you want.
Neither of them can be used with things like:
hello, now that neither of them can be used with things above, why the compiler gets through? what does this definition( " trait M1[F[G[_]]] " ) mean ? can you give some examples for this kind of definition? thanks very much again.
as I tried, trait M1[F[G[_]]] equals the definition of trait M1[F[_[_]]]
but when will this definition been used now that the 3 examples above like [Int]=>>List[List[X]] can not be used in this definition.
It means that M1 is a type of kind ((* -> *) -> *) -> *
Meaning, it has a type parameter of kind (* -> *) -> *
Which means that to create a value of M1 you need to provide a type of that kind.
Like Monad which is defined like Monad[F[_]]
Which means it has kind (* -> *) -> *
Which is the kind M1 needs.
If you look closely to the syntax, it makes sense, Monad[F[_]] looks like F[G[_]]
Again, if you want to provide an interface that operates on values of shapes similar to List[List[Int]] all you need is this:
the compiler tells me:“Type argument List[A] does not have the same kind as its bound [_$2]” in scastie.
then I tried: :kind -v F[List]
it says F[List] is a proper type.
so fft is a value,not a type constructor or type parameter. then how can I define a F[List] value?
can you explain something for me? thank you again.
Which is correct, because List[A] has kind * whereas F expects a type of kind * -> *
Right, because F has kind (* -> *) -> * thus, if you pass it List which has kind * -> * it returns a type of kind *; i.e. a proper type.
The very act of having a variable of such type, means that it is a value (variables can only contain values) it also means that such type is a proper type; i.e. a type of kind * -> *
Again, Functor and Monad are good examples of that.
For example,
Here the M1[TestF],do you mean the fft:F[List] I wrote in my code? and TestList can be a instance of F[List] and a valid parameter as fft:F[List]?
if so, I probably understand this example and the use of such a type constructor.
Thanks very much, especially for a new guy of scala type system like me.
Hope your reply again.
I just wanna know something about the type system, but this feature really frustrates me a lot when first met. especially when it combines with those functor, applicatove and monad. wow. so intricate. but your explanation really helps. thanks again.