What is `class A[_]` useful for? - scala

The types of symbols class A[_] or of def a[_](x: Any) have a type parameter that can't be referenced in the body, thus I don't see where it is useful for and why it compiles. If one tries to reference this type parameter, an error is thrown:
scala> class A[_] { type X = _ }
<console>:1: error: unbound wildcard type
class A[_] { type X = _ }
^
scala> def a[_](x: Any) { type X = _ }
<console>:1: error: unbound wildcard type
def a[_](x: Any) { type X = _ }
^
Can someone tell me if such a type has a use case in Scala? To be exact, I do not mean existential types or higher kinded types in type parameters, only those litte [_] which form the complete type parameter list.

Because I did not get the answers I expected, I brought this to scala-language.
I paste here the answer from Lars Hupel (so, all credits apply to him), which mostly explains what I wanted to know:
I'm going to give it a stab here. I think the use of the feature gets
clear when talking about type members.
Assume that you have to implement the following trait:
trait Function {
type Out[In]
def apply[In](x: In): Out[In]
}
This would be a (generic) function where the return type depends on
the input type. One example for an instance:
val someify = new Function {
type Out[In] = Option[In] def
apply[In](x: In) = Some(x)
}
someify(3) res0: Some[Int] = Some(3)
So far, so good. Now, how would you define a constant function?
val const0 = new Function {
type Out[In] = Int
def apply[In](x: In) = 0
}
const0(3) res1: const0.Out[Int] = 0
(The type const0.Out[Int] is equivalent to Int, but it isn't
printed that way.)
Note how the type parameter In isn't actually used. So, here's how
you could write it with _:
val const0 = new Function {
type Out[_] = Int
def apply[In](x: In) = 0
}
Think of _ in that case as a name for the type parameter which
cannot actually be referred to. It's a for a function on the type
level which doesn't care about the parameter, just like on value
level:
(_: Int) => 3 res4: Int => Int = <function1>
Except …
type Foo[_, _] = Int
<console>:7: error: _ is already defined as type _
type Foo[_, _] = Int
Compare that with:
(_: Int, _: String) => 3 res6: (Int, String) => Int = <function2>
So, in conclusion:
type F[_] = ConstType // when you have to implement a type member def
foo[_](...) // when you have to implement a generic method but don't
// actually refer to the type parameter (occurs very rarely)
The main thing you mentioned, class A[_], is completely symmetric to
that, except that there's no real use case.
Consider this:
trait FlyingDog[F[_]] { def swoosh[A, B](f: A => B, a: F[A]): F[B] }
Now assume you want to make an instance of FlyingDog for your plain
old class A.
new FlyingDog[A] { ... }
// error: A takes no type parameters, expected: one
// (aka 'kind mismatch')
There are two solutions:
Declare class A[_] instead. (Don't do that.)
Use a type lambda:
new FlyingDog[({ type λ[α] = A })#λ]
or even
new FlyingDog[({ type λ[_] = A })#λ]

I had some casual ideas about what it could mean here:
https://issues.scala-lang.org/browse/SI-5606
Besides the trivial use case, asking the compiler to make up a name because I really don't care (though maybe I'll name it later when I implement the class), this one still strikes me as useful:
Another use case is where a type param is deprecated because
improvements in type inference make it superfluous.
trait T[#deprecated("I'm free","2.11") _, B <: S[_]]
Then, hypothetically,
one could warn on usage of T[X, Y] but not T[_, Y].
Though it's not obvious whether the annotation would come before (value parameter-style) or after (annotation on type style).
[Edit: "why it compiles": case class Foo[_](i: Int) still crashes nicely on 2.9.2]

The underscore in Scala indicates an existential type, i.e. an unknown type parameter, which has two main usage:
It is used for methods which do not care about the type parameter
It is used for methods where you want to express that one type parameter is a type constructor.
A type constructor is basically something that needs a type parameter to construct a concrete type. For example you can take the following signature.
def strangeStuff[CC[_], B, A](b:B, f: B=>A): CC[A]
This is a function that for some CC[_] , for example a List[_], creates a List[A] starting from a B and a function B=>A.
Why would that be useful? Well it turns out that if you use that mechanism together with implicits and typeclasses, you can get what is called ad-hoc polymorphism thanks to the compiler reasoning.
Imagine for example you have some higher-kinded type: Container[_] with a hierarchy of concrete implementations: BeautifulContainer[_], BigContainer[_], SmallContainer[_]. To build a container you need a
trait ContainerBuilder[A[_]<:Container[_],B] {
def build(b:B):A[B]
}
So basically a ContainerBuilder is something that for a specific type of container A[_] can build an A[B] using a B.
While would that be useful ? Well you can imagine that you might have a function defined somewhere else like the following:
def myMethod(b:B)(implicit containerBuilder:ContainerBuilder[A[_],B]):A[B] = containerBuilder.build(b)
And then in your code you might do:
val b = new B()
val bigContainer:BigContainer[B] = myMethod(b)
val beautifulContainer:BeautifulContainer[B] = myMethod(b)
In fact, the compiler will use the required return type of myMethod to look for an implicit which satisfies the required type constraints and will throw a compile error if there is no ContainerBuilder which meets the required constraints available implicitely.

That's useful when you deal with instances of parametrized types without caring of the type parameter.
trait Something[A] {
def stringify: String
}
class Foo extends Something[Bar] {
def stringify = "hop"
}
object App {
def useSomething(thing: Something[_]) :String = {
thing.stringify
}
}

Related

How to transfer type parameter through class methods in scala?

In my project, I need to write a generic class, which in a single method handles some types with its handler in a special way (Numeric is used for clarity in the example).
class A[T](val a:T){
def doSomething(b:T):T = a match{
case a : Int => doSomethingWithIntOrDouble(b)
case a : Double => doSomethingWithIntOrDouble(b)
case _ => b
}
def doSomethingWithIntOrDouble(b:T)(implicit ev:Numeric[T]):T =
ev.plus(a,b)
}
<console>:13: error: could not find implicit value for parameter ev: Numeric[T]
case a : Int => doSomethingWithIntOrDouble(b)
^
<console>:14: error: could not find implicit value for parameter ev: Numeric[T]
case a : Double => doSomethingWithIntOrDouble(b)
I think this happens because the compiler picks up the type parameter but not the actual one. Tell me, is there any way around this?
PS Okay If we assume that the answer is correct, then it is necessary to overload the dosomething method to achieve polymorphism.
class A[T](val a:T){
def doSomething(b:T)(implicit ev:Numeric[T]):T = ev.plus(a,b)
def doSomething(b:T):T = b
}
But in this case, another problem arises.
scala> a.doSomething(2)
<console>:13: error: ambiguous reference to overloaded definition,
both method doSomething in class A of type (b: Int)Int
and method doSomething in class A of type (b: Int)(implicit ev: Numeric[Int])Int
match argument types (Int)
a.doSomething(2)
I am not completely sure this is want your want, but I hope it helps.
Basically, you need to forward the evidence that the T type is a Numeric to the outer method. But, you also have to handle the case where it is not.
For that case, you can provide a default value for the implicit parameter like this:
class A[T](val a: T) {
def doSomething(b: T)(implicit ev: Numeric[T] = null): T = Option(ev) match {
case Some(ev) => doSomethingWithNumeric(b)(ev)
case None => b
}
def doSomethingWithNumeric(b: T)(implicit ev: Numeric[T]): T =
ev.plus(a, b)
}
It seems to work.
(new A(10)).doSomething(100) // res: Int = 110
(new A("hey")).doSomething("world") // res: String = "world"
Note that, if you will have many methods, maybe a cleanest solution would be to make A a trait with two implementations, one for numeric types and other for no numeric types.
Make the constructors of both sub classes private and create a factory for A in the companion object which ask for the implicit numeric parameter, and if found it will return a new instance of the numeric subclass.

Validation and capturing errors using an algebra

I came across this article on medium: https://medium.com/#odomontois/tagless-unions-in-scala-2-12-55ab0100c2ff. There is a piece of code that I have a hard time understanding. The full source code for the article can be found here: https://github.com/Odomontois/zio-tagless-err.
The code is this:
trait Capture[-F[_]] {
def continue[A](k: F[A]): A
}
object Capture {
type Constructors[F[_]] = F[Capture[F]]
type Arbitrary
def apply[F[_]] = new Apply[F]
class Apply[F[_]] {
def apply(f: F[Arbitrary] => Arbitrary): Capture[F] = new Capture[F] {
def continue[A](k: F[A]): A = f(k.asInstanceOf[F[Arbitrary]]).asInstanceOf[A]
}
}
}
Here are my questions:
how does the scala compiler solve/handle the Arbitrary type given that the type is declared in an object? It seems to depend on the apply method parameter type but then how does that square to the fact that Capture is an object and you can have multiple apply calls with different types? I came across this post What is the meaning of a type declaration without definition in an object? but it is still not clear to me.
according to the article the code above uses a trick from another library https://github.com/alexknvl. Could you please explain what is the idea behind this pattern? What is it for? I understand that the author used it in order to capture the multiple types of errors that can occur during the login process.
Thanks!
Update:
First question:
Based on the spec when the upper bound is missing it is assumed to be Any. So, Arbitrary is treated as Any, however, it doesn't seem interchangeable with Any.
This compiles:
object Test {
type Arbitrary
def test(x: Any): Arbitrary = x.asInstanceOf[Arbitrary]
}
however, this doesn't:
object Test {
type Arbitrary
def test(x: Any): Arbitrary = x
}
Error:(58, 35) type mismatch;
found : x.type (with underlying type Any)
required: Test.Arbitrary
def test(x: Any): Arbitrary = x
See also this scala puzzler.
This is a little obscure, though legal usage of type aliases. In specification you can read type alias might be used to refer to some abstract type and be used as a type constraint, suggesting compiler what should be allowed.
type X >: L <: U would mean that X, whatever it is, should be bound between L and G - and actually any value that we know fulfill that definition can be used there,
type X = Y is very precise constraint - compiler know that each time we have Y we can call it Y and vice versa
but type X is also legal. We use it usually to declare it in trait or something, but then we put more constraints on it in extending class.
trait TestA { type X }
trait TestB extends TestA { type X = String }
however, we don't have to specify it to a concrete type.
So the code from the question
def apply(f: F[Arbitrary] => Arbitrary): Capture[F] = new Capture[F] {
def continue[A](k: F[A]): A = f(k.asInstanceOf[F[Arbitrary]]).asInstanceOf[A]
}
can be read as: we have Arbitrary type we know nothing of, but we know that if we put F[Arbitrary] into a function, we get Arbitrary.
Thing is, compiler will not let you pass any value as Arbitrary because it cannot prove that your value is of this type. If it could prove that Arbitrary=A you could just write:
def apply(f: F[Arbitrary] => Arbitrary): Capture[F] = new Capture[F] {
def continue[A](k: F[A]): A = f(k)
}
However, it cannot, which is why you are forced to use .asInstanceOf. That is why type X is not equal to saying type X = Any.
There is a reason, why we aren't simply using generics though. How would you pass in a polymorphic function inside? One that does F[A] => A for any A? One way would be to use natural transformation (or ~> or FunctionK) from F[_] to Id[_]. But how messy it would be to use it!
// no capture pattern or other utilities
new Capture[F] {
def continue[A](fa: F[A]): A = ...
}
// using FunctionK
object Capture {
def apply[F[_]](fk: FunctionK[F, Id]): Caputure[F] = new Capture[F] {
def continue[A](fa: F[A]): A = fk(fa)
}
}
Capture[F](new FunctionK[F, Id] {
def apply[A](fa: F[A]): A = ...
})
Not pleasant. Problem is, you cannot pass something like polymorphic function (here [A]: F[A] => A). You can only pass instance with polymorphic method (that is FunctionK works).
So we are hacking this by passing a monomorphoc function with A fixed to type that you cannot instantiate (Arbitrary) because for no type compiler can prove that it matches Arbitrary.
Capture[F](f: F[Arbitrary] => Arbitrary): Capture[F]
Then you are forcing the compiler into thinking that it is of type F[A] => A when you learn A.
f(k.asInstanceOf[F[Arbitrary]]).asInstanceOf[A]
The other part of the pattern is partial application of type parameters of sort. If you did things in one go:
object Capture {
type Constructors[F[_]] = F[Capture[F]]
type Arbitrary
def apply[F[_]](f: F[Arbitrary] => Arbitrary): Capture[F] = new Capture[F] {
def continue[A](k: F[A]): A = f(k.asInstanceOf[F[Arbitrary]]).asInstanceOf[A]
}
}
you would have some issues with e.g. passing Capture.apply as a normal function. You would have to do things like otherFunction(Capture[F](_)). By creating Apply "factory" we can split type parameter application and passing the F[Arbitrary] => Arbitrary function.
Long story short, it is all about letting you just write:
takeAsParameter(Capture[F]) and
Capture[F] { fa => /* a */ }

How can I write a function have a polymorphic return type based on the type argument of its type parameter?

I have some code like this:
sealed trait Foo[A] {
def value: A
}
case class StringFoo(value: String) extends Foo[String]
case class IntFoo(value: Int) extends Foo[Int]
I'd like to have a function which can use the A type given a subtype's type parameter.
// Hypothetical invocation
val i: Int = dostuff[IntFoo](param)
val s: String = dostuff[StringFoo](param)
I can't figure out how to declare dostuff in a way that works. The closest thing I can figure out is
def dostuff[B <: Foo[A]](p: Param): A
But that doesn't work because A is undefined in that position. I can do something like
def dostuff[A, B <: Foo[A]](p: Param): A
But then I have to invoke it like dostuff[String, StringFoo](param) which is pretty ugly.
It seems like the compiler should have all the information it needs to move A across to the return type, how can I make this work, either in standard scala or with a library. I'm on scala 2.10 currently if that impacts the answer. I'm open to a 2.11-only solution if it's possible there but impossible in 2.10
Another option is to use type members:
sealed trait Foo {
type Value
def value: Value
}
case class StringFoo(value: String) extends Foo { type Value = String }
case class IntFoo(value: Int) extends Foo { type Value = Int }
def dostuff[B <: Foo](p: Any): B#Value = ???
// Hypothetical invocation
val i: Int = dostuff[IntFoo](param)
val s: String = dostuff[StringFoo](param)
Note that both solutions mainly work around the syntactic restriction in Scala, that you cannot fix one type parameter of a list and have the compiler infer the other.
As you might know, if you have a parameter of type Foo[A], then you can make the method generic in just A:
def dostuff[A](p: Foo[A]): A = ???
Since that might not always be the case, we can try to use an implicit parameter that can express the relationship between A and B. Since we can't only apply some of the generic parameters to a method call (generic parameter inference is all or nothing), we have to split this into 2 calls. This is an option:
case class Stuff[B <: Foo[_]]() {
def get[A](p: Param)(implicit ev: B => Foo[A]): A = ???
}
You can check the types in the REPL:
:t Stuff[IntFoo].get(new Param) //Int
:t Stuff[StringFoo].get(new Param) //String
Another option along the same lines, but using an anonymous class, is:
def stuff[B <: Foo[_]] = new {
def apply[A](p: Param)(implicit ev: B <:< Foo[A]): A = ???
}
:t stuff[IntFoo](new Param) //Int
Here, I've used apply in stead of get, so you can apply the method more naturally. Also, as suggested in your comment, here I've used <:< in the evidence type. For those looking to learn more about this type of generalized type constraint, you can read more here.
You might also consider using abstract type members instead of generic parameters here. When struggling with generic type inference, this often provides an elegant solution. You can read more about abstract type members and their relationship to generics here.

Understanding the limits of Scala GADT support

The error in Test.test seems unjustified:
sealed trait A[-K, +V]
case class B[+V]() extends A[Option[Unit], V]
case class Test[U]() {
def test[V](t: A[Option[U], V]) = t match {
case B() => null // constructor cannot be instantiated to expected type; found : B[V] required: A[Option[U],?V1] where type ?V1 <: V (this is a GADT skolem)
}
def test2[V](t: A[Option[U], V]) = Test2.test2(t)
}
object Test2 {
def test2[U, V](t: A[Option[U], V]) = t match {
case B() => null // This works
}
}
There are a couple ways to make the error change, or go away:
If we remove the V parameter on trait A (and case class B), the 'GADT-skolem' part of the error goes away but the 'constructor cannot be instantiated' part remains.
If we move the U parameter of the Test class to the Test.test method, the error goes away. Why ? (Similarly, the error is not present in Test2.test2)
The following link also identifies that problem, but I do not understand the provided explanation. http://lambdalog.seanseefried.com/tags/GADTs.html
Is this an error in the compiler ? (2.10.2-RC2)
Thank you for any help with clarifying that.
2014/08/05: I have managed to further simplify the code, and provide another example where U is bound outside the immediate function without causing a compilation error. I still observe this error in 2.11.2.
sealed trait A[U]
case class B() extends A[Unit]
case class Test[U]() {
def test(t: A[U]) = t match {
case B() => ??? // constructor cannot be instantiated to expected type; found : B required: A[U]
}
}
object Test2 {
def test2[U](t: A[U]) = t match {
case B() => ??? // This works
}
def test3[U] = {
def test(t: A[U]) = t match {
case B() => ??? // This works
}
}
}
Simplified like that this looks more like a compiler bug or limitation. Or am I missing something ?
Constructor patterns must conform to the expected type of the pattern, which means B <: A[U], a claim which is true if U is a type parameter of the method presently being called (because it can be instantiated to the appropriate type argument) but untrue if U is a previously bound class type parameter.
You can certainly question the value of the "must conform" rule. I know I have. We generally evade this error by upcasting the scrutinee until the constructor pattern conforms. Specifically,
// Instead of this
def test1(t: A[U]) = t match { case B() => ??? }
// Write this
def test2(t: A[U]) = (t: A[_]) match { case B() => ??? }
Addendum: in a comment the questioner says "The question is simple on why it doesn't works with type parameter at class level but works with at method level." Instantiated class type parameters are visible externally and have an indefinite lifetime, neither of which is true for instantiated method type parameters. This has implications for type soundness. Given Foo[A], once I'm in possession of a Foo[Int] then A must be Int when referring to that instance, always and forever.
In principle you could treat class type parameters similarly inside a constructor call, because the type parameter is still unbound and can be inferred opportunistically. That's it, though. Once it's out there in the world, there's no room to renegotiate.
One more addendum: I see people doing this a lot, taking as a premise that the compiler is a paragon of correctness and all that's left for us to do is ponder its output until our understanding has evolved far enough to match it. Such mental gymnastics have taken place under that tent, we could staff Cirque de Soleil a couple times over.
scala> case class Foo[A](f: A => A)
defined class Foo
scala> def fail(foo: Any, x: Any) = foo match { case Foo(f) => f(x) }
fail: (foo: Any, x: Any)Any
scala> fail(Foo[String](x => x), 5)
java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
at $anonfun$1.apply(<console>:15)
at .fail(<console>:13)
... 33 elided
That's the current version of scala - this is still what it does. No warnings. So maybe ask yourselves whether it's wise to be offering the presumption of correctness to a language and implementation which are so trivially unsound after more than ten years of existence.
Looks like it is a compiler caveat. From this, martin odersky puts it as:
In the method case, what you have here is a GADT:
Patterns determine the type parameters of an corresponding methods in the scope of a pattern case.
GADTs are not available for class parameters.
As far as I know, nobody has yet explored this combination, and it looks like it would be quite tricky to get this right.
PS: Thanks to #retronym who provided the reference from discussion here
On why it throws an error in case of class:
This works:
sealed trait A[-K, +V]
case class B[+V]() extends A[Option[Unit], V]
case class Test[U]() {
def test[V, X <: Unit](t: A[Option[X], V]) = t match {
case B() => null
}
def test2[V](t: A[Option[U], V]) = Test2.test2(t)
}
object Test2 {
def test2[U, V](t: A[Option[U], V]) = t match {
case B() => null // This works
}
}
To examplain why the compiler threw an error: Try doing this:
scala> :paste
// Entering paste mode (ctrl-D to finish)
abstract class Exp[A]{
def eval:A = this match {
case Temp(i) => i //line-a
}
}
case class Temp[A](i:A) extends Exp[A]
// Exiting paste mode, now interpreting.
To understand this, from §8.1.6: above Temp is a polymorphic type. If the case class is polymorphic then:
If the case class is polymorphic, then its type parameters are
instantiated so that the instantiation of c conforms to the expected
type of the pattern. The instantiated formal parameter types of c’s
primary constructor are then taken as the expected types of the
component patterns p 1 , . . . , p n . The pattern matches all objects
created from constructor invocations c(v1 , . . . , v n ) where each
element pattern p i matches the corresponding value v i .
i.e. the compiler smartly tries to instantiate Temp in line-a such that it conforms to the primary constructor of this( which if above compiled successfully then in case of Temp(1) would be something like Exp[Int] and hence compiler instantiates Temp in line-a with parameter as Int.
Now in our case: the compiler is trying to instantiate B. It sees that t is of type A[Option[U],V] where U is already fixed and obtained from class parameter and V is generic type of method. On trying to initialize B it tries to create in such a way that it ultimately gets A[Option[U],V]. So with B() it is somehow trying to get A[Option[U],V]. But it cant as B is A[Option[Unit],V]. Hence it ultimately cannot initialize B. Fixing this makes it work
Its not required in case of test-2 because: The compiler as explained in above process is trying to initialize type parameter of B. It knows t has type parameter [Option[U], V] where U and V are both generic wrt method and are obtained from argument. It tries to initialize B based on the agrument. If the argument was new B[String] it tries deriving B[String] and hence U is automatically obtained as Option[Unit]. If the argument was new A[Option[Int],String] then it obviously it wont match.
The difference has to do with what information the compiler and runtime have in each case, combined with what the restrictions on the types are.
Below the ambiguity is clarified by having U be the trait and class parameter, and X be the method type paramter.
sealed trait A[U]
case class B(u: Unit) extends A[Unit]
class Test[U]() {
def test(t: A[U]) = t match {
case B(u) => u // constructor cannot be instantiated to expected type; found : B required: A[U]
}
}
object Test2 {
def test2[X](t: A[X]) = t match {
case B(x) => x // This works
}
def test3[X] = {
def test(t: A[X]) = t match {
case B(x) => x // This works
}
}
}
Test2.test2(new B(println("yo")))
In Test2.test2, the compiler knows that an instance of A[X] will be provided, with no limits on X.It can generate code that inspects the parameter provided to see if it is B, and handle the case.
In class Test method test, the compiler knows not that some A[X] is provided when called, but that some specific type, U, is presented. This type U can be anything. However, the pattern match is on an algebraic data type. This data type has exactly one valid variation, of type A[Unit]. But this signature is for A[U] where U is not limited do Unit. This is a contradiction. The class definition says that U is a free type parameter, the method says it is Unit.
Imagine you instantiate Test:
val t = new Test[Int]()
Now, at the use site, the method is:
def test(t: A[Int])
There is no such type A[Int]. Pattern matching on B is when the compiler inspects this condition. A[U] for any U is incompatible with the type, hence "constructor cannot be instantiated to expected type; found : B required: A[U]"
The difference with the method versus class type parameter is that one is bound while one is free, at the time the method is called in the runtime.
Another way to think about it is that defining the method
def test(t: A[U])
implies that U is Unit, which is inconsistent with the class declaration that U is anything.
Edit: this is not an answer to the question. I'm keeping it for reference (and the comments).
The link you provided already gives the answer.
In the case of the parameterised method, U is infered from the argument of the actual method call. So, the fact that the case B() was chosen implies that U >: Unit (otherwise the method could not have been called with a B) and the compiler is happy.
In the case of the parameterized class, U is independent from the method argument. So, the fact that the case B() was chosen tells the compiler nothing about U and it can not confirm that U >: Unit. I think if you add such a type bound to U it should work. I haven't tried it, though.
The compiler is absolutely correct with its error message. An easy example should describe the issue well:
sealed trait A[U]
class B extends A[Unit]
class T[U] {
val b: A[Unit] = new B
f(b) // invalid, the compiler can't know which types are valid for `U`
g(b) // valid, the compiler can choose an arbitrary type for `V`
def f(t: A[U]) = g(t)
def g[V](t: A[V]) = ???
}
f and g have different type signatures. g takes an A[V] where V is an arbitrary type parameter. On the other hand, f takes an A[U] where U is not arbitrary but dependent from the outer class T.
The compiler does not know what type U can be at the moment when it typechecks T - it needs to typecheck an instantiation of T to find out which types are used. One can say that U is a concrete type inside of T, but a generic type outside of it. This means it has to reject every code fragment that gets inside of T more concrete about the type of U.
Calling g from inside f is clearly allowed - after all an arbitrary type for V can be chosen, which is U in this case. Because U is never again referenced in g it doesn't matter what type it may have.
Your other code example underlies the same limitations - it is just an example that is more complex.
Btw, that this code
def test3[U] = {
def test(t: A[U]) = t match {
case B() => ??? // This works
}
}
is valid looks weird to me. It doesn't matter if U is bound by a class or a method - from inside of the binding scope we can't give any guarantees about its type, therefore the compiler should reject this pattern match too.

Is it possible to write a method in Scala returning objects with different type parameter?

Is it possible to write a method in Scala which returns an object of a type-parameterized class with different type paramter ? Something like this:
class A[T]
def f(switch: Boolean): A = if(switch) new A[Int] else new A[String]
Please note: The Code above is fictional to show the type of problem; The code above does not make semantically sense.
The code above will not compile because return type A is not parameterized.
You can, and you can even do it with type-safety with the aid of implicit arguments that encapsulate the pairings:
class TypeMapping[+A,B] {
def newListB = List.empty[B]
}
trait Logical
object True extends Logical
object False extends Logical
implicit val mapFalseToInt = new TypeMapping[False.type,Int]
implicit val mapTrueToString = new TypeMapping[True.type,String]
def f[A <: Logical,B](switch: A)(implicit tmap: TypeMapping[A,B]) = tmap.newListB
scala> f(True)
res2: List[String] = List()
scala> f(False)
res3: List[Int] = List()
You do have to explicitly map from boolean values to the custom True and False values.
(I have chosen List as the target class just as an example; you could pick anything or even make it generic with a little more work.)
(Edit: as oxbow_lakes points out, if you need all possible return values to be represented on the same code path, then this alone won't do it, because the superclass of List[Int] and List[String] is List[Any], which isn't much help. In that case, you should use an Either. My solution is for a single function that will be used only in the True or False contexts, and can maintain the type information there.)
One way of expressing this would be by using Either;
def f(switch: Boolean) = if (switch) Left(new A[Int]) else Right(newA[String])
This of course returns an Either[A[Int], A[String]]. You certainly cannot (at the moment) declare a method which returns some parameterized type P, with some subset of type parameters (i.e. only Int or String).
The language ceylon has union types and I understand the intention is to add these to scala in the near future, in which case, you could define a method:
def f(switch: Boolean): A[Int|String] = ...
Well, you could do something like that.
scala> class A {
| type T
| }
defined class A
scala> def f(b: Boolean): A = if(b) new A { type T = Int } else new A { type T = String }
f: (b: Boolean)A
But this is pointless. Types are a compile time information, and that information is getting lost here.
How about an absolutely minimal change to the "fictional code"? If we just add [_] after the "fictional" return type, the code will compile:
class A[T]
def f(switch: Boolean):A[_] = if(switch) new A[Int] else new A[String]
It is worth noting that A[_] is not the same as A[Any]. A[T] does not need to be defined covariant for the code to compile.
Unfortunately, information about the type gets lost.