These four versions compile but i'm curious about context in which we should prefer one option rather than another.
// 1
def f[N, S <: Seq[N]](s: S)
// 2
def f[N, S[N] <: Seq[N]](s: S[N])
They are pretty similar when use 1 rather than 2
2 impose that S have N as generic parameter as 1 but then what is the difference between these two ?
Then we have more general settings.
// 3
def f[N, S[X] <: Seq[X]](s: S[N])
// 3.a
def f[N, S[X] <: Seq[X]](s: S[N]): S[Int]
From what i humbly understood 3 authorize to extract the generic container type to reuse it later and get something like 3.a.
But what is the meaning of the undeclared X generic parameter, i suppose it's a way to declare something special but i don't get it.
// 4
def f[N, S[X] <: Seq[_]](s: S[N])
I don't know what to say about 4 except than from what i know Seq[_] stands for Seq[Any]
Finally i'm simply curious to have more information about these tools and their specificity to get things done more properly.
The idea here is that the first
Nparameter andNmentioned inS[N] <: Seq[N]are completely independent parameters. They are just sharing the same name.Nmentioned inS[N]is visible only in a scope of its bound<: Seq[N].Nused in parameter definition(s: S[N])comes from firstNas this is the onlyNparameter visible for parameter type definition. So instead ofNinS[N] <: Seq[N]you can use any letter and this will not affect your parameter type at any way.Here you just ignoredXparameter.Edit: as @alexey-romanov mentioned in a comment. There is difference between
S[X] <: Seq[X]andS[X] <: Seq[_]Here is an example showing the difference:
The problem here is as type constrictor is a kind of "function on types", we can define such "function" accepting one type as a parameter but returning type parametrized by another parameter not related to parameter used in type constructor. (See type
Foo)Passing
fooval tof2is fine becauseXis infered to String andFoo[String]is a "subtype"(actually they are equal) ofSeq[Int], but when we passfootof1theXis still aStringbutFoo[String]is not "subtype" ofSeq[String](because Foo[String]==Seq[Int] not subtype of Seq[String])And here you said that
Nused inSeq[N]is the same as first parameterN. So this is the sameN